Tweet

Sorting

The sort function sorts a list (an array). The default is to sort alphabetically. However, you can define your own sorts to get around numbers and complex data structures.

Sort an array of strings

    #!/usr/bin/perl
    use strict;
    use warnings;

    my @strings = ("Becky", "Simon", "Bianca", "Steven", "Greg", "Andrew");

    my @sorted_strings = sort @strings;
    print "@sorted_strings\n";

This gives you the following output:

    Andrew Becky Bianca Greg Simon Steven

Sort an array of numbers

The Perl sort function sorts by strings instead of by numbers. If you were to use:

    #!/usr/bin/perl
    use strict;
    use warnings;

    my @numbers = (23, 1, 22, 7, 109, 9, 65, 3);

    my @sorted_numbers = sort @numbers;
    print "@sorted_numbers\n";

The output you would see would be:

    1 109 22 23 3 65 7 9

To sort numerically, declare your own sort block and use the flying saucer operator <=>:

    #!/usr/bin/perl
    use strict;
    use warnings;

    my @numbers = (23, 1, 22, 7, 109, 9, 65, 3);

    my @sorted_numbers = sort {$a <=> $b} @numbers;
    print "@sorted_numbers\n";

The output would now be:

    1 3 7 9 22 23 65 109

Note that $a and $b do not need to be declared, even with use strict on, because they are special sorting variables.

Sorting backwards

To sort backwards you need to declare your own sort block, and simply put $b before $a.

For example, the standard sort is as follows:

    #!/usr/bin/perl
    use strict;
    use warnings;

    my @strings = ("Becky", "Simon", "Bianca", "Steven", "Greg", "Andrew");

    my @sorted_strings = sort @strings;
    print "@sorted_strings\n";

The output would be:

    Andrew Becky Bianca Greg Simon Steven

To do the same, but in reverse order:

    #!/usr/bin/perl
    use strict;
    use warnings;

    my @strings = ("Becky", "Simon", "Bianca", "Steven", "Greg", "Andrew");

    my @sorted_strings = sort {$b cmp $a} @strings;
    print "@sorted_strings\n";

The output is:

    Steven Simon Greg Bianca Becky Andrew

And for numbers:

    #!/usr/bin/perl
    use strict;
    use warnings;

    my @numbers = (23, 1, 22, 7, 109, 9, 65, 3);

    my @sorted_numbers = sort {$b <=> $a} @numbers;
    print "@sorted_numbers\n";

The output is:

    109 65 23 22 9 7 3 1

Of course, in both these cases there is another way:

    #!/usr/bin/perl
    use strict;
    use warnings;

    my @strings = ("Becky", "Simon", "Bianca", "Steven", "Greg", "Andrew");

    my @sorted_strings = reverse sort @strings;
    print "@sorted_strings\n";

The output is:

    Steven Simon Greg Bianca Becky Andrew

And

    #!/usr/bin/perl
    use strict;
    use warnings;

    my @numbers = (23, 1, 22, 7, 109, 9, 65, 3);

    my @sorted_numbers = reverse sort {$a <=> $b} @numbers;
    print "@sorted_numbers\n";

The output is:

    109 65 23 22 9 7 3 1

Sorting hashes

You can use sort to order hashes. For example, if you had a hash as follows:

    #!/usr/bin/perl
    use strict;
    use warnings;

    my %data = (
        bananas => 1,
        oranges => 7,
        apples => 12,
        mangoes => 3,
        pears => 8,
    );

And you wanted to display the fruit sorted alphabetically, you could do this:

    #!/usr/bin/perl
    use strict;
    use warnings;

    my %data = (
        bananas => 1,
        oranges => 7,
        apples => 12,
        mangoes => 3,
        pears => 8,
    );
    foreach my $fruit (sort keys %data) {
        print $fruit . ": " . $data{$fruit} . "\n";
    }

Output:

    apples: 12
    bananas: 1
    mangoes: 3
    oranges: 7
    pears: 8

If you wanted to sort the same hash by the values (i.e. the number beside each fruit), you could do the following:

    #!/usr/bin/perl
    use strict;
    use warnings;

    my %data = (
        bananas => 1,
        oranges => 7,
        apples => 12,
        mangoes => 3,
        pears => 8,
    );
    # Using <=> instead of cmp because of the numbers
    foreach my $fruit (sort {$data{$a} <=> $data{$b}} keys %data) {
        print $fruit . ": " . $data{$fruit} . "\n";
    }

Output:

    bananas: 1
    mangoes: 3
    oranges: 7
    pears: 8
    apples: 12

Sorting complex data structures

You can also use sort to sort more complex data structures. For example, if you had an array of hashes:

    my @people = (
        { name => 'Becky', age => 23},
        { name => 'Simon', age => 43},
        { name => 'Bianca', age => 29},
        { name => 'Steven', age => 23},
        { name => 'Greg', age => 50},
        { name => 'Andrew', age => 19},
    );

And you wish to display the data about the uses, in alphabetical order, you could do the following:

    #!/usr/bin/perl
    use strict;
    use warnings;

    my @people = (
        { name => 'Becky', age => 23},
        { name => 'Simon', age => 43},
        { name => 'Bianca', age => 29},
        { name => 'Steven', age => 23},
        { name => 'Greg', age => 50},
        { name => 'Andrew', age => 19},
    );

    foreach my $person (sort {$a->{name} cmp $b->{name}} @people) {
        print $person->{name} . " is " . $person->{age} . "\n";
    }

The output is:

    Andrew is 19
    Becky is 23
    Bianca is 29
    Greg is 50
    Simon is 43
    Steven is 23

Providing a sort subroutine

Rather than writing the code inline, you can also pass in a subroutine name. The subroutine needs to return an integer less than, equal to, or greater than 0. Do not modify the $a and $b variables as they are passed in by reference, and modifying them will probably confuse your sorting.

    #!/usr/bin/perl
    use strict;
    use warnings;

    my @people = (
        { name => 'Becky', age => 23},
        { name => 'Simon', age => 43},
        { name => 'Bianca', age => 29},
        { name => 'Steven', age => 23},
        { name => 'Greg', age => 50},
        { name => 'Andrew', age => 19},
    );

    foreach my $person (sort byage @people) {
        print $person->{name} . " is " . $person->{age} . "\n";
    }

    sub byage {
        $a->{age} <=> $b->{age};
    }

The output would be:

    Andrew is 19
    Becky is 23
    Steven is 23
    Bianca is 29
    Simon is 43
    Greg is 50

More

To find out more, run the command:

    perldoc -f sort
Revision: 1.7 [Top]