-----Original Message-----
From: Barry Brevik <[email protected]>
To: [email protected]
Sent: Wed, Mar 31, 2010 8:36 pm
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
> "; 
>?? } 
>? 
> 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 


here's a multi-key recursive approach that may fill the bill:
?
use warnings;
use strict;
?
use List::Util qw(shuffle);

MAIN: {? # begin main loop
?
# test words in desired sorted order
my @words = qw(
??? CALIBRATION1
??? CALIBRATION02
??? LABVIEW-1
??? LABVIEW-2
??? LABVIEW-4
??? LABVIEW-11
??? LABVIEW-12
??? LABVIEW-114
??? YESTECH-L3-RW1
??? YESTECH-L03-RW2
??? YESTECH-L4-RW125
??? );
?
my $ordered = join ' ', @words;? # words in desired order
?
my @sorted = sort multi_key shuffle @words;
?
print "$_ \n" for @sorted;
?
die "FAILED: not desired order" unless $ordered eq join ' ', @sorted;
?
print "desired order";
?
}? # end main loop
?
exit;

sub multi_key {
?
??? # assumes $a and $b are always defined.
??? return length($a) <=> length($b) unless length($a) and length($b);
?
??? # at this point, neither $a nor $b are empty string.
??? my ($a_alpha, $a_numeric, $a_dashed) = split_key($a);
??? my ($b_alpha, $b_numeric, $b_dashed) = split_key($b);
?
??? return $a_alpha?? cmp $b_alpha
??????? || $a_numeric <=> $b_numeric
??????? || do { local ($a, $b) = ($a_dashed, $b_dashed);? multi_key(); }
???????? ;
?
??? }
?
sub split_key {
??? $_[0] =~ m{ \A ([[:alpha:]]*) (\d*) (?<= .) (?: - (.+))? \z }xms
??????? or die "malformed key: ``$_[0]''";
??? return $1, $2 ? 0+$2 : 0, defined($3) ? $3 : '';
??? }
?
Output:
?
>perl recursive_multikey_sort_1.pl
CALIBRATION1
CALIBRATION02
LABVIEW-1
LABVIEW-2
LABVIEW-4
LABVIEW-11
LABVIEW-12
LABVIEW-114
YESTECH-L3-RW1
YESTECH-L03-RW2
YESTECH-L4-RW125
desired order

?

_______________________________________________
ActivePerl mailing list
[email protected]
To unsubscribe: http://listserv.ActiveState.com/mailman/mysubs

Reply via email to