Hi,
You can solve this using a schwartzian transformation :

@x= map {
        ( @t = split /(\d+)/ );
        if ( $#t > $max )
            {
                undef $sort;
                $max = $#t;
                foreach ( 0 .. $max )
                    {
                        $occ = $_ + 1;
                        $operator = $occ % 2 ? 'cmp' : '<=>';
                        $sort .= "\$a->[$occ] $operator \$b->[$occ]";
                        $sort .= '||' unless $_ == $#t;
                    }
            }
        [ $_, @t, $sort ]
    }
  keys %mdata;

$cmd=qq!print foreach map { "\$_->[0]\n" } sort { $sort } \...@x!;

eval qq!$cmd!;

---------------------------------------
CALIBRATION1
CALIBRATION02
LABVIEW-1
LABVIEW-2
LABVIEW-4
LABVIEW-11
LABVIEW-12
LABVIEW-114
YESTECH-L3-RW1
YESTECH-L03-RW2
YESTECH-L4-RW125

Bour9

-----Message d'origine-----
De : [email protected] 
[mailto:[email protected]] De la part de Francisco 
Zarabozo
Envoyé : jeudi 1 avril 2010 06:00
À : Barry Brevik; [email protected]
Objet : Re: Help with sort

Hi,

I wrote this sorting subroutine for those cases. It works very fine to me, I 
hope it works for you. Include this subroutine in your code and then only use 
lines like the following when sorting data:

for my $key (sort alphaANDnumeric keys %mdata) {
    print "$key\n";
}

The subroutine I wrote is the following:

sub alphaANDnumeric {
        my ($aa, $bb) = ($a, $b);
        while (length($aa) and length($bb) and substr($aa, 0, 1) eq substr($bb, 
0,
1)) {
                $aa = substr($aa, 1);
                $bb = substr($bb, 1);
        }
        return 0 unless (length($aa) or length($bb));
        $aa =~ s/^(\d+|\D+).*?$/$1/;
        $bb =~ s/^(\d+|\D+).*?$/$1/;
        if (defined $aa and $aa =~ /\d/ and defined $bb and $bb =~ /\d/) {
                return $aa <=> $bb;
        } else {
                return $a cmp $b;
        }
}


HTH

Francisco Zarabozo


--------------------------------------------------
From: "Barry Brevik" <[email protected]>
Sent: Wednesday, March 31, 2010 6:36 PM
To: <[email protected]>
Subject: Help with sort

> I'm having a problem sorting data items that are alpha-numeric strings.
> I know how to do it if the string is all alpha or all numeric, but the
> combo eludes me.
>
> Take as example the following code. It is my desire that the machine
> names be processed in the order that they have been loaded into the
> hash. This is an example only- the machine names will not actually be
> loaded in order. Also, there will not always be "dashes" separating the
> alpha from the numbers:
>
>  use strict;
>  use warnings;
>
>  my %mdata =
>  (
>    'CALIBRATION1',    1,
>    'CALIBRATION02',   1,
>    'LABVIEW-1',       1,
>    'LABVIEW-2',       1,
>    'LABVIEW-4',       1,
>    'LABVIEW-11',      1,
>    'LABVIEW-12',      1,
>    'LABVIEW-114',     1,
>    'YESTECH-L3-RW1',  1,
>    'YESTECH-L03-RW2', 1,
>    'YESTECH-L4-RW125',1
>  );
>
>  foreach my $key (sort(keys(%mdata)))
>  {
>    print "$key\n";
>  }
>
> The output of this code is as follows, and you can see that the sort
> order is not what I wanted:
>
>  CALIBRATION02
>  CALIBRATION1
>  LABVIEW-1
>  LABVIEW-11
>  LABVIEW-114
>  LABVIEW-12
>  LABVIEW-2
>  LABVIEW-4
>  YESTECH-L03-RW2
>  YESTECH-L3-RW1
>  YESTECH-L4-RW125
>
> Any ideas on how to get this to come out in the "right" order?
>
> Barry Brevik
> _______________________________________________
> ActivePerl mailing list
> [email protected]
> To unsubscribe: http://listserv.ActiveState.com/mailman/mysubs
> 
_______________________________________________
ActivePerl mailing list
[email protected]
To unsubscribe: http://listserv.ActiveState.com/mailman/mysubs
_______________________________________________
ActivePerl mailing list
[email protected]
To unsubscribe: http://listserv.ActiveState.com/mailman/mysubs

Reply via email to