Friday, September 06, 2013

How to sort a hash in Perl?

Gabor has a nice article about sorting hashes in Perl.

I thought I would piggy-back off Gabor's article and demonstrate how you can do something similar with a couple of CPAN modules specifically designed for processing hashes and lists.

use strict;
use warnings;
use 5.010;
use List::MoreUtils qw(natatime);
use Hash::MoreUtils qw(hashsort);

my %planets = (
    Mercury => 0.4,
    Venus => 0.7,
    Earth => 1,
    Mars => 1.5,
    Ceres => 2.77,
    Jupiter => 5.2,
    Saturn => 9.5,
    Uranus => 19.6,
    Neptune => 30,
    Pluto => 39,
    Charon => 39,
    );

# Sort the keys of the hash using the hashsort function in the  Hash::MoreUtils module
my @array_of_pairs  = hashsort \%planets;

# Leverage List::MoreUtils natatime function to create an iterator to peel off 2 items at a time
my $it = natatime 2, @array_of_pairs;
while ( (my $a, $b) = $it->() ) {
    say "$a $b";
}

__END__

Output...

Ceres 2.77
Charon 39
Earth 1
Jupiter 5.2
Mars 1.5
Mercury 0.4
Neptune 30
Pluto 39
Saturn 9.5
Uranus 19.6
Venus 0.7



5 comments:

jnagyjr said...

what's the point of the sort if you're not using the numerical values? Seems kind of silly since you could have just alphabetically sorted them by hand.

Anonymous said...

Don't you mean local ($a, $b) ?

Anonymous said...

One other way:

*** Also see Sort::MultipleFields, Sort::Rank


use Moose;
use Data::Printer;

my $hash = {
a => {
pos => 9,
key2 => 1,
},
b => {
pos => 8,
key2 => 1,
},
c => {
pos => 7,
key2 => 0,
},
d => {
pos => 6,
key2 => 1,
},
e => {
pos => 5,
key2 => 1,
},
f => {
pos => 4,
key2 => 1,
},
g => {
pos => 3,
key2 => 1,
},
h => {
pos => 2,
key2 => 1,
},
i => {
pos => 1,
key2 => 1,
},
};


my @sorted = sort { $hash->{$a}->{pos} <=> $hash->{$b}->{pos} } keys $hash;

warn p @sorted;

Camera.co.id Toko Kamera Murah di Indonesia said...

Thank's.. great article

Camera.co.id Toko Kamera Murah di Indonesia

Jeffrey Black said...

Thanks @jnagyjr. I suppose that's true. I was trying to illustrate the usage of List::MoreUtils, and Hash::MoreUtils by playing off Gabor's article.