Jordy224 has asked for the wisdom of the Perl Monks concerning the following question:

Greetings, I have designed an Array of Hash - with the following representative structure:
@array [0] %Hash { name => proteobacteria, size => 30 [1] %Hash { phylum => alphabacteria, size => 50 [2] %Hash { name => cytophaga, size => 10
... Question: How do I sort the array by the value of the hash key “size" Such that it is arranged in a new array in descending order? ie.
@newarray [0] %Hash {name => alphabacteria size => 50
so far my script looks as follows...

@newarray = sort {$$hash{$b} <=> $$hash{$a} } @array, keys %Hash;

Thanks In advance.

Replies are listed 'Best First'.
Re: How to sort by the key value of an Array of Hash structure?
by moritz (Cardinal) on Jul 30, 2008 at 16:25 UTC
    Remember that $a and $b are the array items that are being sorted, in your case hash references.

    So you need to access the size key if you want to sort by it: @newarray = sort { $b->{size} <=> $a->{size} @array;

    If you want to see your data structures, I recommend Data::Dumper.

Re: How to sort by the key value of an Array of Hash structure?
by whakka (Hermit) on Jul 30, 2008 at 17:04 UTC

    Stolen from this Q&A node, you can do a Schwartzian Transformation by doing:

    my @sorted = map{ $_->[1] } sort { $b->[0] <=> $a->[0] } map{ [ $_->{size}, $_ ] } @{$aoh}; print Dumper \@sorted;

      Unless the "hashes" are actually tied or overloaded objects with really slow access times, I expect moritz's much simpler sort { $a->{size} <=> $b->{size} } will also be faster (but I'm ready to be corrected).

Re: How to sort by the key value of an Array of Hash structure?
by dwm042 (Priest) on Jul 30, 2008 at 18:19 UTC
    I rearranged your structure a little bit, for clarity, and you are awfully close to sorting it. For example:

    #!/usr/bin/perl -w use strict; my @array = ( { name => "proteobacteriai", size => 30 }, { phylum => "alphabacteria", size => 50 }, { name => "cytophaga", size => 10 }, ); for (@array) { print "Size (out of order) = ",$_->{size}, "\n"; } my @newarray = sort { $a->{size} <=> $b->{size} } @array; for (@newarray) { print "Size = ",$_->{size}, "\n"; }
    yields

    C:\Code>perl sort_aoh.pl Size (out of order) = 30 Size (out of order) = 50 Size (out of order) = 10 size = 10 size = 30 size = 50