Sorting is a very common operation in computing, and it is something computers are very good for because of their speed of operation. A good sorting operation is, however, quite complicated. There are different ways of sorting (alphabetically, numerically, etc.) and as the data grows, efficiency becomes a major concern.
Perl uses a very efficient sorting algorithm, quicksort. It is implemented in the function sort( )
.
sort is a bit more complex than other Perl functions. It takes a block of code and a list as input and returns a sorted list:
@sorted = sort { [code] } @unsorted;
By default, sort sorts alphabetically in ascending order and does not need the code block:
@sorted = sort(@unsorted);
Other sorts have to be specified in the code block.
Sorting is based on comparing values. As with other operators, Perl has different comparison operators for strings and numbers, respectively:
for strings:cmp
for numbers:<=>
The functions also comes with two special variables that perform the comparison at any given time:
$a and $b
where $a represents the larger value and $b the smaller one.
In complete notation, the default sort function would look as follows
@sorted = sort { $a cmp $b } @unsorted;
which accomplishes the same as
@sorted = sort(@unsorted);
In order to reverse the sorting order, only the two special variables have to be exchanged
@sorted = sort { $b cmp $a } @unsorted;
will sort in descending order.
Sorting numbers works just the same way, except that the numerical operator must be used, or the numbers will be sorted alphabetically. (Characters and strings will not be sorted by the <=> operator.)
@sorted = sort { $a <=> $b } @unsorted;
Since hashes are stored internal in non-sequential order, we can not create a sorted hash. However, we can create arrays of sorted keys or values and thus access the hash in a sorted manner.
Sorting a hash by keys can be done easily via the keys() function, which returns an array of keys:
foreach $key (sort keys(%my_hash)) { [do something with $my_hash{$key}] }
Sorting by value, we have to compare the values in the comparison code:
foreach $key (sort { $my_hash{$a} cmp $my_hash{$b} } keys(%my_hash)) { [do something with $my_hash{$key}] }