Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I sort a hash's keys naturally?

I have a Perl hash whose keys start with, or are, numbers.

If I use,

foreach my $key (sort keys %hash) {
    print $hash{$key} . "\n";
}

the list might come out as,

0
0001
1000
203
23

Instead of

0
0001
23
203
1000
like image 636
lamcro Avatar asked Dec 20 '08 17:12

lamcro


People also ask

Is hash keys are sorted in Perl?

Because a hash is unsorted, if it's contents are required in a particular order then they must be sorted on output. Perl uses the '%' symbol as the variable sigil for hashes.

How do I sort a hash by value in Perl?

First sort the keys by the associated value. Then get the values (e.g. by using a hash slice). my @keys = sort { $h{$a} <=> $h{$b} } keys(%h); my @vals = @h{@keys};

How do I sort an array of hashes in Perl?

Perl's built in sort function allows us to specify a custom sort order. Within the curly braces Perl gives us 2 variables, $a and $b, which reference 2 items to compare. In our case, these are hash references so we can access the elements of the hash and sort by any key we want.


2 Answers

foreach my $key (sort { $a <=> $b} keys %hash) {
    print $hash{$key} . "\n";
}

The sort operation takes an optional comparison "subroutine" (either as a block of code, as I've done here, or the name of a subroutine). I've supplied an in-line comparison that treats the keys as numbers using the built-in numeric comparison operator '<=>'.

like image 200
Paul Tomblin Avatar answered Sep 28 '22 09:09

Paul Tomblin


Paul's answer is correct for numbers, but if you want to take it a step further and sort mixed words and numbers like a human would, neither cmp nor <=> will do. For example,

  9x
  14
  foo
  fooa
  foolio
  Foolio
  foo12
  foo12a
  Foo12a
  foo12z
  foo13a

Sort::Naturally takes care of this problem, providing the nsort and ncmp routines.

like image 23
3 revs, 2 users 62% Avatar answered Sep 28 '22 08:09

3 revs, 2 users 62%