- my %score = ("barney" => 195, "fred" => 205, "dino" => 30);
-
@new_values = sort {$score{$b} <=>$score{ $a}} keys %score;
-
print @new_values;
fredbarneydino
if there are two equal values in the hash my %score = ("barney" => 195, "fred" => 205,
"dino" => 30, "bamm-bamm" => 195,); and we want them be in ASCIIbetical order. the sort function should be
- {$score{$b}<=>$score{$a} or $a cmp $b}
if the spaceship sees two different scores, that’s the com-parison we want to use. It returns −1 or 1, a true value, so the low-precedence short-circuit or will mean that the rest of the expression will be skipped, and the comparison we want is returned.
But if the spaceship sees two identical scores, it returns 0, a false value, and thus
the cmp operator gets its turn at bat, returning an appropriate ordering value considering
the keys as strings.
There’s no reason that your sort subroutine has to be limited to two levels of sorting,
of course. Here the Bedrock library program puts a list of patron ID numbers in order
according to a five-level sort.† This example sorts according to the amount of each
patron’s outstanding fines (as calculated by a subroutine &fines, not shown here), the
number of items they currently have checked out (from %items), their name (in order
by family names, then by personal name, both from hashes), and finally by the patron’s
ID number, in case everything else is the same:
@patron_IDs = sort {
&fines($b) <=> &fines($a) or
$items{$b} <=> $items{$a} or
$family_name{$a} cmp $family_name{$a} or
$personal_name{$a} cmp $family_name{$b} or
$a <=> $b
} @patron_IDs;
阅读(405) | 评论(0) | 转发(0) |