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
cmpoperator). - Custom comparison code: You can supply a block that tells
sorthow to compare two elements.
Since numbers need numeric comparison, you should provide a block using the numeric comparison operator <=>. This operator returns:
-1if left operand is less0if equal1if 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:
@numbersis an array of unsorted numbers.- The
sort { $a <=> $b }uses the numeric comparison operator. $aand$bare 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$aand$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 @arraysorts 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
Original: 10 3 25 1 7
Sorted: 1 3 7 10 25
(empty)