Skip to content

Perl Sorting Guide — Custom Comparisons, Stable Sort, and Advanced Techniques

DodaTech Updated 2026-06-28 3 min read

In this tutorial, you will learn about Perl Sorting Guide. We cover key concepts, practical examples, and best practices to help you master this topic.

Perl sort function takes a comparison block with $a and $b package variables, using cmp for string comparison and <=> for numeric comparison -- with the Schwartzian transform for sorting by expensive computed values and GRT (Guttman-Rosler Transform) for maximum speed.

Basic Sort

my @numbers = (5, 3, 8, 1, 9, 2);
my @strings = qw(banana apple cherry date);

# Default sort (string comparison)
my @sorted = sort @numbers;           # (1, 2, 3, 5, 8, 9) - strings!

# Numeric sort
my @numeric = sort { $a <=> $b } @numbers;  # (1, 2, 3, 5, 8, 9)

# Reverse sort
my @desc = sort { $b <=> $a } @numbers;     # (9, 8, 5, 3, 2, 1)

Custom Comparisons

# Sort by string length
my @words = qw(long longer longest short);
my @by_length = sort { length($a) <=> length($b) } @words;

# Sort by multiple criteria
my @people = (
    { name => "Alice", age => 30 },
    { name => "Bob",   age => 25 },
    { name => "Alice", age => 20 },
);

my @sorted = sort {
    $a->{name} cmp $b->{name}  # first by name
    ||
    $a->{age} <=> $b->{age}    # then by age
} @people;

Case-Insensitive Sort

my @mixed = qw(Apple banana Cherry date);

# Case-insensitive
my @sorted = sort { lc($a) cmp lc($b) } @mixed;

# Using fc (fold case, Unicode-safe, Perl 5.16+)
use feature 'fc';
my @sorted2 = sort { fc($a) cmp fc($b) } @mixed;

Schwartzian Transform

# Without transform (computes length for each comparison)
my @sorted = sort { length($a) <=> length($b) } @words;

# With Schwartzian transform (compute once, cache)
my @sorted = map  { $_->[0] }
             sort { $a->[1] <=> $b->[1] }
             map  { [$_, length($_)] }
             @words;

# Step by step:
# 1. map: wrap each word with [word, length]
# 2. sort: compare by cached length
# 3. map: extract original words

Sort on Hash Values

my %score = (
    Alice => 95,
    Bob   => 87,
    Carol => 92,
);

# Sort keys by value (ascending)
my @by_score = sort { $score{$a} <=> $score{$b} } keys %score;

# Sort keys by value (descending)
my @top = sort { $score{$b} <=> $score{$a} } keys %score;

# Sort by value, then by key
my @sorted = sort {
    $score{$b} <=> $score{$a}  # high scores first
    ||
    $a cmp $b                   # alphabetical tie-breaker
} keys %score;

Common Mistakes

1. Forgetting $a and $b are package variables

$a and $b are global in the comparison block. Don't declare them with my.

2. Using == instead of <=> or cmp

== tests equality (returns true/false). <=> returns -1, 0, or 1. Use <=> for numeric sort.

3. Modifying $a or $b in the comparison

The sort comparison should be a pure function. Side effects break the sort algorithm.

Practice Questions

1. How do you sort numbers numerically? sort { $a <=> $b } @numbers. The default sort compares as strings.

2. What is the Schwartzian transform? A technique that precomputes sort keys in a map-sort-map chain to avoid recomputing expensive comparisons.

3. How do you sort a hash by values? sort { $hash{$a} cmp $hash{$b} } keys %hash for strings, or <=> for numbers.

FAQ

{{< faq question="Is Perl's sort stable?" >}} No. Perl's sort is not guaranteed stable (equal elements may not preserve original order). {{< /faq >}}

{{< faq question="What is the GRT (Guttman-Rosler Transform)?" >}} An optimization that packs sort keys into a single string for ultra-fast sorting: my @sorted = map { substr($_, 4) } sort map { pack("N", length) . $_ } @data. {{< /faq >}}

{{< faq question="Can I sort in place?" >}} sort returns a new list. To sort in place, assign back: @array = sort @array. {{< /faq >}}

What's Next

Now learn about map and grep for list processing.

Topic Description Link
Map/Grep List transformation and filtering {{< ref "20-maps-filters" >}}
DBI Database interface {{< ref "21-dbi" >}}

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro