Summary: in this tutorial, you will learn how to use the Perl sort function to sort lists alphabetically and numerically. In addition, you will learn some advanced sorting techniques with custom sort subroutines.
Introduction to the Perl sort function
Perl sort()
function sorts a list and returns a sorted list. The original list remains intact. The sort()
function has three forms:
sort list;
sort block list;
sort subroutine_name list
Code language: Perl (perl)
In the first form, you pass a list to the sort()
function and get a new-sorted list in alphabetical order.
To sort a list based on numerical order, you use the second form of the sort()
function and pass a block that compares two numbers. The sort block uses special package variables: $a
and $b
when doing the comparison between elements in the list.
The spaceship <=>
operator is used for comparing numbers, and the cmp
operator is used for comparing strings. Both operators return -1, 0 or 1 if the left operand is less than, equal or greater than the right operand.
Sometimes, the sort criteria are complex, you need to write a custom subroutine and pass the name of the subroutine to the sort()
function. This is where the third form of the sort()
function comes to play.
Perl sort function examples
In the following sections, we will give you some examples of how to use the sort()
function, from a simple to complex one, so that you can understand how it works.
Sorting a list alphabetically example
The following example demonstrates how to sort a list alphabetically:
#!/usr/bin/perl
use warnings;
use strict;
my @list = sort qw(perl sort function alphabetically);
print "@list\n";
Code language: Perl (perl)
The output is:
alphabetically function perl sort
Code language: JavaScript (javascript)
By default, the sort()
function sorts elements of a list with a string comparison in ascending order.
Sorting a list numerically example
The Perl sort()
function sorts strings as characters. For example, if we use the sort()
function to sort a list of integers as follows:
#!/usr/bin/perl
use warnings;
use strict;
my @nums = sort qw/1 11 2 22 10 100/;
print "@nums\n";
Code language: PHP (php)
We got the following output:
1 10 100 11 2 22
Code language: Perl (perl)
This is alphabetical order, not the numerical order as we expected.
To sort the numbers numerically, we need to provide a sort block as the following example:
#!/usr/bin/perl
use warnings;
use strict;
my @nums = sort { $a <=> $b } qw/1 11 2 22 10 100/;
print "@nums\n";
Code language: Perl (perl)
We got the numbers sorted numerically.
1 2 10 11 22 100
When we use the sort()
functions with a block, Perl iterates the list and assigns elements to the special package variables $a
and $b
. We used the spaceship operator (<=>) to compare the elements numerically.
We can use a subroutine instead of the spaceship operator ( <=>
) to achieve the same result as shown following:
#!/usr/bin/perl
use warnings;
use strict;
my @nums = sort compare qw/1 11 2 22 10 100/;
print "@nums\n";
# compare two numbers
sub compare{
if($a < $b){
return -1;
}elsif($a == $b){
return 0;
}else{
return 1;
}
}
Code language: Perl (perl)
We created a subroutine named compare()
to compare two numbers and passed the subroutine name to the sort()
function.
Perl reverse sorting example
Sometimes, you want a list reversed. You may do it quickly as follows:
@rlist = reverse sort @list;
Code language: Perl (perl)
However, this is inefficient, especially for a large list because it sorts the @list
in ascending order first, and then reverses the list in descending order.
If you want to sort the numbers in descending order, you use $b <=> $a
for sorting numerically and $b cmp $a
for sorting alphabetically as follows:
#!/usr/bin/perl
use warnings;
use strict;
my @nums = sort { $b <=> $a } qw(1 11 2 22 10 100);
my @chars = sort { $b cmp $a } qw(perl sort function alphabetically);
print "@nums\n";
print "@chars\n";
Code language: Perl (perl)
The following is the output:
100 22 11 10 2 1
sort perl function alphabetically
Code language: JavaScript (javascript)
Complex sorting example
Sorting becomes complex when you want to sort a list of multiple values. In this case, you need to use a sort block or a sort subroutine.
Suppose, we have a list of products with name, price and discount:
iPhone 600 USD 0.5 Samsung Galaxy 600 USD 0.8 Nexus 299 USD 0.1
We want to sort the products by price in ascending order. If two products have the same price, we want to sort them by discount in descending order.
To sort the products by price in ascending order, we use the following expression:
$a->{price} <=> $b->{price}
Code language: Perl (perl)
To sort the products by the same price by discount in descending order, we use the following expression:
$b->{discount} <=> $a->{discount}
Code language: Perl (perl)
Now, we can combine the two expressions by use the || operator as follows:
$a->{price} <=> $b->{price} ||
$b->{discount} <=> $a->{discount}
Code language: Perl (perl)
The ||
operator is short-circuited so that if the first expression returns 1 (or true), Perl does not evaluate the second expression, otherwise, Perl evaluates the second one.
You can use the same technique to sort a list by more than two criteria.
The following example illustrates how to sort a list based on multiple values:
#!/usr/bin/perl
use warnings;
use strict;
my @products = (
{
name => 'iPhone',
price => 600,
discount => 0.5,
},
{
name => 'Nexus',
price => 299,
discount => 0.1,
},
{
name => 'Samsung Galaxy',
price => 600,
discount => 0.8,
}
);
@products = sort {
$a->{price} <=> $b->{price} ||
$b->{discount} <=> $a->{discount}
} @products;
foreach my $p (@products){
printf "%-15s %2d USD %2.1f\n" => @{$p}{qw(name price discount)};
}
Code language: Perl (perl)
Nexus 299 USD 0.1
Samsung Galaxy 600 USD 0.8
iPhone 600 USD 0.5
Code language: CSS (css)
In this tutorial, you’ve learned how to use the Perl sort()
function to sort a list alphabetically and numerically. In addition, you learned how to sort a list based on multiple values.