data-structures intermediate

How to sort an array numerically in Perl?

Question

How to sort an array numerically in Perl?

Sorting an array numerically in Perl is a common task, but it requires a slight adjustment from the default sorting behavior. By default, Perl's sort function sorts elements as strings, which means numbers are sorted lexically rather than by their numeric value. For example, 10 would come before 2 because "1" is lexicographically before "2".

How Perl’s sort Works

The built-in sort function uses either:

  • Default string comparison: Without arguments, it compares elements as strings (like cmp operator).
  • Custom comparison code: You can supply a block that tells sort how to compare two elements.

Since numbers need numeric comparison, you should provide a block using the numeric comparison operator <=>. This operator returns:

  • -1 if left operand is less
  • 0 if equal
  • 1 if greater

Example: Numeric Sort

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

my @numbers = (10, 3, 25, 1, 7);

# Sort numerically ascending using the spaceship operator <=> 
my @sorted = sort { $a <=> $b } @numbers;

print "Original: @numbers\n";
print "Sorted:   @sorted\n";

In this code:

  • @numbers is an array of unsorted numbers.
  • The sort { $a <=> $b } uses the numeric comparison operator.
  • $a and $b are special sort variables representing two elements being compared.
  • The sorted array is stored in @sorted.

Key Perl Concepts in This Example

  • Sigils: The @ sigil denotes an array (@numbers), while $ is for scalar variables like $a and $b.
  • Sort context: The comparison block is called repeatedly to determine the order of elements.
  • TMTOWTDI: Perl’s “There’s More Than One Way To Do It” philosophy means you can also use other methods, such as the Schwartzian transform, especially for complex sorting.

Common Pitfalls

  • Using default sort on numbers: sort @array sorts elements string-wise, so (10, 2) becomes (10, 2) — not sorted numerically.
  • Using <==> instead of <=>: The numeric comparison operator is <=>, not <==>.
  • Locale issues: If you rely on locales, string comparison can behave unexpectedly, so always use numeric sort for numbers.

Advanced Note

Since Perl 5.10, you can also use the sort with a named subroutine or use the state feature to optimize. But for most cases, the block with $a <=> $b is the simplest, fastest, and clearest way.

Verified Code

Executed in a sandbox to capture real output. • v5.34.1 • 6ms

Tip: edit code and use “Run (Browser)”. Server runs always execute the published, verified snippet.
STDOUT
Original: 10 3 25 1 7
Sorted:   1 3 7 10 25
STDERR
(empty)

Was this helpful?

Related Questions