How to sort hash keys in Perl?
Question
How to sort hash keys in Perl?
Sorting hash keys in Perl is a common task when you want to process or display hash data in a specific order. Since hashes in Perl are inherently unordered collections of key-value pairs, you must explicitly retrieve and sort the keys using the sort function.
Basic Syntax to Sort Hash Keys
To get the keys sorted alphabetically (string-wise), you can use:
my %hash = (b => 2, a => 1, c => 3);
my @sorted_keys = sort keys %hash;
print "Sorted keys: @sorted_keys\n";
This prints:
Sorted keys: a b c
sort, by default, performs a string-wise comparison, returning the keys in ASCIIbetical order. You pass keys %hash to it, which returns a list of all keys.
Sorting Numeric Keys
If your hash keys are numbers stored as strings and you want a numeric sort rather than alphabetical, you'll want to use a numeric comparison block with sort:
my %hash = (10 => 'x', 2 => 'y', 1 => 'z');
my @sorted_keys = sort { $a <=> $b } keys %hash;
print "Numerically sorted keys: @sorted_keys\n";
This outputs:
Numerically sorted keys: 1 2 10
Sorting Keys by Their Associated Values
You can also sort the keys based on corresponding values. For example, to sort keys by ascending value:
my %hash = (a => 30, b => 10, c => 20);
my @keys_sorted_by_value = sort { $hash{$a} <=> $hash{$b} } keys %hash;
print "Keys sorted by values: @keys_sorted_by_value\n";
Output:
Keys sorted by values: b c a
Important Perl Concepts Illustrated
keys %hashreturns an unordered list of hash keys.- The
sortfunction returns a newly sorted list without modifying the hash. $aand$bare special variables used withinsortblocks to represent pairwise elements being compared.- Sorting defaults to string comparison unless you specify numeric comparison with
<=>. - Hash keys are strings by default, so numeric keys might sort unexpectedly without numeric comparison.
- Remember Perl's TMTOWTDI ("There’s more than one way to do it")—you can use different sort criteria depending on your needs.
Common Gotchas
- Sorting hash keys directly modifies the order of the returned list, not the hash itself (hashes remain unordered).
- Beware of string vs numeric sorting.
- Sorting very large hashes may affect performance.
- Remember that string comparison is case-sensitive by default—“Z” sorts before “a”. For case-insensitive sorting, you can use:
sort { lc($a) cmp lc($b) } keys %hash.
Complete Runnable Example
use strict;
use warnings;
my %hash = (
banana => 3,
apple => 5,
orange => 1,
blueberry => 2,
);
# Sort keys alphabetically
my @alphabetical = sort keys %hash;
print "Alphabetical keys: @alphabetical\n";
# Sort keys by associated values (numeric ascending)
my @by_values = sort { $hash{$a} <=> $hash{$b} } keys %hash;
print "Keys sorted by associated values: @by_values\n";
# Case-insensitive alphabetical sort
my %case_hash = ('Banana' => 1, 'apple' => 2, 'Orange' => 3);
my @ci_sorted = sort { lc($a) cmp lc($b) } keys %case_hash;
print "Case-insensitive sorted keys: @ci_sorted\n";
Running this script will print:
Alphabetical keys: apple banana blueberry orange
Keys sorted by associated values: orange blueberry banana apple
Case-insensitive sorted keys: apple Banana Orange
This demonstrates several common sorting techniques for hash keys in Perl and highlights the flexibility Perl offers. Adjust your sort block to fit the exact criteria you need.
Verified Code
Executed in a sandbox to capture real output. • v5.34.1 • 5ms
Sorted keys: a b c
(empty)