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

Hello Monks!

I have been having trouble getting the sorting of a multi-level hash to do what I want.

#!/usr/bin/perl use strict; use warnings; my $VAR1 = { '212' => { '42' => 6, '49' => 6, '41' => 1 }, '282' => { '38' => 4, '39' => 1, '37' => 2 } }; my %reg = %{$VAR1}; my $c = 1; # sort by the item with the most sub-keys first # if there is a tie sort by sub-keys foreach my $item (sort { scalar keys (%{$reg{$b}})<=>scalar keys (%{$r +eg{$a}}) || $a<=>$b } keys %reg){ + foreach my $case (sort {$reg{$item}{$a}<=>$reg{$item}{$b}} keys %{ +$reg{$item}}){ print "$c = $item:$case\n"; $c++; } }

I would like to sort first by the count of the top-level sub-keys. In case of a tie sort by the sub-keys themselves.

I would like to get:
1 = 282:37 2 = 282:38 3 = 282:39 4 = 212:41 5 = 212:42 6 = 212:49
There are 3 keys for item 282 and 3 keys for item 312 so now we sort by sub-key. The item sub-key values have no relevance for this sort
TIA
Glenn

Replies are listed 'Best First'.
Re: Lost with a multi-level hash sort
by NetWallah (Canon) on May 25, 2012 at 21:11 UTC
    You sorted by VALUES, instead of KEYS, then VALUES. Try:
    foreach my $item (sort { scalar keys (%{$reg{$b}})<=>scalar keys (%{$r +eg{$a}}) || $b<=>$a } keys %reg){ + foreach my $case (sort {$a<=>$b || $reg{$item}{$a} <=> $reg{$item} +{$b}} keys %{$reg{$item}}){ print "$c = $item:$case\n"; $c++; } } __OUTPUT__ 1 = 282:37 2 = 282:38 3 = 282:39 4 = 212:41 5 = 212:42 6 = 212:49

                 I hope life isn't a big joke, because I don't get it.
                       -SNL

      That works great! Thanks! Glenn