Sometimes you need to sort your data by multiple columns (for example, sorting a user list by age and then by last name).
If the fields you want to compare don't need any kind of processing then just put all the comparisons together (ordered by importance), separated by '||':
Example:
#-- order by age (oldest first) and the by last name
@ordered_users = sort { $b->age <=> $a->age || $a->last cmp $b->last } @users;
In case you need to do some computation to obtain the fields you want to order by, then it's better to precompute the fields first and then do the sort, otherwise your sort routine could potentially be quite inefficient.
As an example, let's say you want to order a user list by length of last name and then alphabetically by first name; to do this, you must do the following:
1. Use map to create a temporary array of arrays, the first elements of each row of the resulting array will have the values to sort by, the last element will be the row itself.
@temp = map { [ length $_[1], $_[0], $_ ] } @users;
2. Sort the resulting array using the precomputed fields
@temp = sort { $a->[0] <=> $b->[0] || $a->[1] cmp $b->[1] } temp;
3. In the previous step you obtained the ordered array, so use map to obtain the original row
@sorted_users = map { $_->[2] } @temp;
You can put all 3 steps in a single sentence like this:
@sorted_users =
map { $_->[2] } # step 3
sort { $a->[0] <=> $b->[0] || $a->[1] cmp $b->[1] } # step 2
map { [ length $_[1], $_[0], $_ ] } # step 1
@users;





