With very few, rare exceptions the simplest (and easiest) way to sort stuff in perl is simply to use the sort
builtin.
sort
takes an optional argument, either a block or a subname, which can be used to control how sort evaluates which of the two elements it is comparing at any given moment is greater.
See sort on perldoc for further information.
If you require a "natural" sort function, where you get the sequence 0, 1, 2, 3, ...
instead of 0, 1, 10, 11, 12, 2, 21, 22, 3, ...
, then use the perl module Sort::Naturally which is available on CPAN (and commonly available as a package on most distros).
In your case, if you need a pure numeric sort, the following will be quite sufficient:
use Sort::Naturally; #Assuming Sort::Naturally is installed
sub main {
my @a = (-23,3,234,-45,0,32,12,54,-10000,1);
#Choose one of the following
@a = sort @a; #Sort in "ASCII" ascending order
@a = sort { $b cmp $a } @a; #Sort in reverse of the above
@a = nsort @a; #Sort in "natural" order
@a = sort { ncmp($b, $a) } @a; #Reverse of the above
print "$_\n" foreach @a; #To see what you actually got
}
It is also worth mentioning the use sort 'stable';
pragma which can be used to ensure that sorting occurs using a stable algorithm, meaning that elements which are equal will not be rearranged relative to one another.
As a bonus, you should be aware that sort
can be used to sort data structures as well as simple scalars:
#Assume @a is an array of hashes
@a = sort { $a->{name} cmp $b->{name} } @; #Sort @a by name key
#Sort @a by name in ascending order and date in descending order
@a = sort { $a->{name} cmp $b->{name} || $b->{date} cmp $a->{date} } @a;
#Assume @a is an array of arrays
#Sort @a by the 2nd element of the arrays it contains
@a = sort { $a->[1] cmp $b->[1] } @a;
#Assume @a is an array of VERY LONG strings
#Sort @a alphanumerically, but only care about
#the first 1,000 characters of each string
@a = sort { substr($a, 0, 1000) cmp substr($b, 0, 1000) } @a;
#Assume we want to "sort" an array without modifying it:
#Yes, the names here are confusing. See below.
my @idxs = sort { $a[$a] cmp $a[$b] } (0..$#a);
print "$a[$_]\n" foreach @idxs;
#@idxs contains the indexes to @a, in the order they would have
#to be read from @a in order to get a sorted version of @a
As a final note, please remember that $a
and $b
are special variables in perl, which are pre-populated in the context of a sorting sub or sort block; the upshot is that if you're working with sort
you can always expect $a
and $b
to contain the next two elements being compared, and should use them accordingly, but do NOT do my $a;
, e.g., or use variables with either name in non-sort-related stuff. This also means that naming things %a
or @a
, or %b
or @b
, can be confusing -- see the final section of my example above.