We don't bite newbies here... much | |
PerlMonks |
perlfunc:sortby gods (Initiate) |
on Aug 24, 1999 at 22:43 UTC ( [id://344]=perlfunc: print w/replies, xml ) | Need Help?? |
sortSee the current Perl documentation for sort. Here is our local, out-dated (pre-5.6) version: sort - sort a list of values
sort SUBNAME LIST sort BLOCK LIST sort LIST
Sorts the
LIST and returns the sorted list value. If
SUBNAME or
BLOCK is omitted,
sort()s in standard string comparison order. If
SUBNAME is specified, it gives the name of a
subroutine that returns an integer less than, equal to, or greater than
In the interests of efficiency the normal calling code for subroutines is
bypassed, with the following effects: the subroutine may not be a recursive
subroutine, and the two elements to be compared are passed into the
subroutine not via You also cannot exit out of the sort block or subroutine using any of the loop control operators described in the perlsyn manpage or with goto().
When Examples:
# sort lexically @articles = sort @files;
# same thing, but with explicit sort routine @articles = sort {$a cmp $b} @files;
# now case-insensitively @articles = sort {uc($a) cmp uc($b)} @files;
# same thing in reversed order @articles = sort {$b cmp $a} @files;
# sort numerically ascending @articles = sort {$a <=> $b} @files;
# sort numerically descending @articles = sort {$b <=> $a} @files;
# sort using explicit subroutine name sub byage { $age{$a} <=> $age{$b}; # presuming numeric } @sortedclass = sort byage @class;
# this sorts the %age hash by value instead of key # using an in-line function @eldest = sort { $age{$b} <=> $age{$a} } keys %age;
sub backwards { $b cmp $a; } @harry = ('dog','cat','x','Cain','Abel'); @george = ('gone','chased','yz','Punished','Axed'); print sort @harry; # prints AbelCaincatdogx print sort backwards @harry; # prints xdogcatCainAbel print sort @george, 'to', @harry; # prints AbelAxedCainPunishedcatchaseddoggonetoxyz
# inefficiently sort by descending numeric compare using # the first integer after the first = sign, or the # whole record case-insensitively otherwise
@new = sort { ($b =~ /=(\d+)/)[0] <=> ($a =~ /=(\d+)/)[0] || uc($a) cmp uc($b) } @old;
# same thing, but much more efficiently; # we'll build auxiliary indices instead # for speed @nums = @caps = (); for (@old) { push @nums, /=(\d+)/; push @caps, uc($_); }
@new = @old[ sort { $nums[$b] <=> $nums[$a] || $caps[$a] cmp $caps[$b] } 0..$#old ];
# same thing using a Schwartzian Transform (no temps) @new = map { $_->[0] } sort { $b->[1] <=> $a->[1] || $a->[2] cmp $b->[2] } map { [$_, /=(\d+)/, uc($_)] } @old;
If you're using strict, you MUST NOT declare
@articles = sort {$main::b <=> $main::a} @files; or just
@articles = sort {$::b <=> $::a} @files;
but if you're in the
@articles = sort {$FooPack::b <=> $FooPack::a} @files;
The comparison function is required to behave. If it returns inconsistent
results (sometimes saying |
|