Christopher Yee Mon wrote: > I have an array of strings whose members consist of a number followed by > a comma followed by a text string > > e.g. > 1,fresh > 2,testurl > > I want to sort by descending numerical order according to the number > part so I made this sort subroutine > > sub by_counter_field { > my($a, $b) = @_; > $a =~ s/^(.*?),.*/$1/g; > $b =~ s/^(.*?),.*/$1/g; > > if ($a > $b) { -1 } elsif ($a < $b) { 1 } else { 0 } > } > > and sorted it with > sort by_counter_field @array; > and it didn't work. > > I've also tried replacing > if ($a > $b) { -1 } elsif ($a < $b) { 1 } else { 0 } > with > $b <=> $a > and it still didn't work. > > I also tried this > sort { ($b =~ /(.*?),.*/)[0] <=> ($a =~ /(.*?),.*/)[0] } @array; > and it didn't work either. > > I can't figure it out for the life of me > > Any assistance would be deeply appreciated.
You misunderstand the way $a and $b work. It is an ugly mechanism, but when 'sort' calls your comparison subroutine the global variables $a and $b are already set to the two values to be compared. What is even more hazardous is that if you modify them as you have tried to do with s/// you will change the values in the list you are sorting. If the derivation is non-trivial then I usually write code that evaluates lexical variables $aa and $bb from $a and $b, and then simply compare them with <=> or 'cmp' as appropriate. The code below is a working rewrite of your program. I hope it helps. Rob use strict; use warnings; no warnings 'qw'; my @data = qw/ 99,tomato 12,pear 1,fresh 2,testurl 16,summary 0,zero 76,trombones 88,fatso /; sub by_counter_field { my $aa = $a =~ /^(\d+)/ ? $1 : 0; my $bb = $b =~ /^(\d+)/ ? $1 : 0; $bb <=> $aa; } my @sorted = sort by_counter_field @data; print map "$_\n", @sorted; -- To unsubscribe, e-mail: beginners-unsubscr...@perl.org For additional commands, e-mail: beginners-h...@perl.org http://learn.perl.org/