@nums = (1,20,10,100,19,32,4); print join(' ',sort(@nums)); # prints 1 10 100 19 20 32 4To accomodate this and many other cases where a lexigraphic sort is not appropriate, you can pass perl a block of statements describing how perl should compare pairs of objects in order to properly sort your data. This block of statements must refer to the two values being compared as
$a
and $b
, and must return the value -1 when $a
is less than $b
,
0 when $a
equals $b
, and 1 when $a
is greater than $b
.
Note that this is exactly the behavior of the builtin cmp and
<=>
comparison operators (Section 3.4). Thus, the solution
to the problem of sorting numbers is simple:
@nums = (1,20,10,100,19,32,4); print join(' ',sort({$a <=> $b} @nums)); # prints 1 4 10 19 20 32 100The expression provided must be enclosed in curly braces. Also note that, like a filehandle in a
print
statement (Section $a
and $b
.)
While this method of sorting may seem unusual, it offers a great deal of flexibility. For example, if we wish to perform a sort of a list of strings, ignoring their case, we can use the lc function to convert the strings to lower case before comparison.
@names = ("andy","Alice","bob","Brad"); print join(' ',sort(@names)); #prints Alice Brad andy bob print join(' ',sort({lc($a) cmp lc($b)} @names)); #prints Alice andy bob Brad
More complex sorting can also be accomplished. Suppose we have a hash named
%accounts
, whose keys represent the names of clients, and whose values
represent the corresponding client's account balance. We would like to sort
the keys of %accounts
so that the client with the largest balance is first,
the next largest second, and so on. Reversing the order of the sort is easy; simply
reverse the roles of $a
and $b
. Since we want to sort the keys by
the value of %accounts
corresponding to the keys, we simply use the value
of the hash in our sorting expression:
@skeys = sort({$accounts{$b} <=> $accounts{$a}} keys(%accounts));