Search code examples
arraysperlsortinghashhash-of-hashes

Perl sort by hash value in array of hashes or hash of hashes


Can anybody tell me what I am doing wrong here? I have tried just about every possible combination of array / hash type and sort query I can think of and cannot seem to get this to work.

I am trying to sort the hash ref below by value1 :

my $test = {
    '1' => { 'value1' => '0.001000', 'value2' => 'red'},
    '2' => { 'value1' => '0.005000', 'value2' => 'blue'},
    '3' => { 'value1' => '0.002000', 'value2' => 'green'},
    '7' => { 'value1' => '0.002243', 'value2' => 'violet'},
    '9' => { 'value1' => '0.001005', 'value2' => 'yellow'},
    '20' => { 'value1' => '0.0010200', 'value2' => 'purple'}
};

Using this sort loop:

foreach (sort { $test{$a}->{'value1'} <=> $test{$b}->{'value1'} } keys \%{$test} ){
    print "key: $_ value: $test->{$_}->{'value1'}\n"
}

I get:

key: 1 value: 0.001000
key: 3 value: 0.002000
key: 7 value: 0.002243
key: 9 value: 0.001005
key: 2 value: 0.005000
key: 20 value: 0.0010200

I have tried with integers and the same thing seems to happen.

I don't actually need to loop through the hash either I just want it ordered for later use. Its easy to do with an array of hashes, but not so with a hash of hashes..?


Solution

  • Don't call keys on a reference. Call it on the actual hash.

    Also, this $test{$a}->, should be $test->{$a}, because $test is a hash reference.

    foreach (sort { $test->{$a}{'value1'} <=> $test->{$b}{'value1'} } keys %{$test} ){
        print "key: $_ value: $test->{$_}->{'value1'}\n"
    }
    

    If you had use strict; and use warnings; turned on, you would've gotten the following error to alert you to an issue:

    Global symbol "%test" requires explicit package name