Question

I have the following data structure

my %HoH = {
      'foo1' => {
                        'bam' => 1,
                        'zip' => 0,
                      },
      'foo2' => {
                         'bam' => 0,
                         'zip' => 1,
                         'boo' => 1
                       }
    };

I would like to sort KEY1 (foo1 or foo2) by the VALUE stored in 'zip' in order from greatest to least.

Here's how I'm doing it.

use strict; use warnings;
use Data::Dumper;
my @sorted;
foreach my $KEY1 (keys %HoH) {
    # sort KEY1 by the value 'zip' maps to in descending order
    @sorted = sort {$HoH{$KEY1}{'zip'}{$b} <=> 
        $HoH{$KEY1}{'zip'}{$a}} keys %HoH;
}

print Dumper(\@sorted);

I'm getting an weird warning: Reference found where even-sized list expected at test.pl line 6. Also print Dumper(\@sorted); is printing

$VAR1 = [
      'HASH(0x1b542a8)'
    ];

When it should be printing

$VAR1 = [
      ['foo2', 'foo1']
    ];

Since foo2 has 1 zip and foo1 has 0 zip.

Was it helpful?

Solution

  • %HoH is declared as a hash, but is defined as a hashreference. Use parentheses (...) instead of braces {...}.
  • You don't need to loop through the hash to sort it. Sort will take care of that.
  • if you sort {...} keys %HoH, then the special variables $a and $b represent the keys of %HoH as it performs the sort.
  • $a and $b are in reverse order because your expected result is in decreasing order. (Update: Oh I just noticed that you had that in the first place.)
  • The zip value in the nested hash is $HoH{$KEY}{'zip'}, which is what you should sort by.

    use strict;
    use warnings;
    use Data::Dumper;
    
    my %HoH = (
          'foo1' => {
                            'bam' => 1,
                            'zip' => 0,
                          },
          'foo2' => {
                             'bam' => 0,
                             'zip' => 1,
                             'boo' => 1
                           }
        );
    
    my @sorted = sort {$HoH{$b}{'zip'} <=> $HoH{$a}{'zip'}} keys %HoH;
    print Dumper \@sorted;
    

Note that the result of this code will give you an array:

$VAR1 = [
      'foo2',
      'foo1'
];

... not a nested array:

$VAR1 = [
     ['foo2', 'foo1']
];
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top