### Re^2: hash of hashes sort second level keys

by kennethk (Abbot)
 on Feb 19, 2010 at 22:01 UTC ( #824269=note: print w/replies, xml ) Need Help??

in reply to Re: hash of hashes sort second level keys
in thread hash of hashes sort second level keys

While it does increase your complexity, I fail to see why hash flattening or restructuring will not accomplish your goal - the solutions presented here are certainly applicable to your scenario:

#!/usr/bin/perl use strict; use warnings; my %sorthash = (); \$sorthash{'10'}{'20'}{1}{2}{3}= '1'; \$sorthash{'40'}{'50'}{1}{4}{3}= '4'; \$sorthash{'20'}{'30'}{3}{4}{3}= '2'; # Flatten my @flat_array = (); for my \$key1 (keys %sorthash) { for my \$key2 (keys %{\$sorthash{\$key1}} ) { for my \$key3 (keys %{\$sorthash{\$key1}{\$key2}} ) { for my \$key4 (keys %{\$sorthash{\$key1}{\$key2}{\$key3}} ) { for my \$key5 (keys %{\$sorthash{\$key1}{\$key2}{\$key3}{\$k +ey4}} ) { push @flat_array, [\$key1, \$key2, \$key3, \$key4, \$ke +y5, \$sorthash{\$key1}{\$key2}{\$key3}{\$key4}{\$key5}]; } } } } } # Sort flat array for my \$entry (sort { \$a->[3] <=> \$b->[3] or \$a->[2] <=> \$b->[2] } @fl +at_array) { print join ", ", @\$entry; print "\n"; }

If that's getting a little deep in terms of nested loops, you can write a recursive crawler to flatten the list:

#!/usr/bin/perl use strict; use warnings; my %sorthash = (); \$sorthash{'10'}{'20'}{1}{2}{3}= '1'; \$sorthash{'40'}{'50'}{1}{4}{3}= '4'; \$sorthash{'20'}{'30'}{3}{4}{3}= '2'; # Flatten my @flat_array = hash_crawler(\%sorthash); # Sort flat array for my \$entry (sort { \$a->[3] <=> \$b->[3] or \$a->[2] <=> \$b->[2] } @fl +at_array) { print join ", ", @\$entry; print "\n"; } sub hash_crawler { my (\$value, @prefix_array) = @_; my @results = (); if (ref \$value) { for (keys %\$value) { push @results, hash_crawler(\$value->{\$_},@prefix_array,\$_) +; } } else { push @results, [@prefix_array, \$value]; } return @results; }

Update: Fixed bug as per rubasov's post below.

Replies are listed 'Best First'.
Re^3: hash of hashes sort second level keys
by rubasov (Friar) on Feb 19, 2010 at 22:42 UTC
It's not totally clear for me what does it mean "trying to sort the entire hr on the keys of layer 4 first and layer 3 second", but if it means to sort by the 4th column as the key and 3rd column as a subkey, then probably you wanted to write this to sort the flattened array:
sort { \$a->[3] <=> \$b->[3] or \$a->[2] <=> \$b->[2] } @flat_array

"if it means to sort by the 4th column as the key and 3rd column as a subkey" is exactly what I was doing. That is very nice! This is exactly what I was looking for, great answer. I will rewrite some code and see how it goes. Thanks again for the replies!

Create A New User
Node Status?
node history
Node Type: note [id://824269]
help
Chatterbox?
 [Discipulus]: ;=) [erix]: that's not a setter but a pointer [erix]: (but what's in a name?) Discipulus aka NodeReaper studying perlguts..

How do I use this? | Other CB clients
Other Users?
Others studying the Monastery: (9)
As of 2017-05-24 07:43 GMT
Sections?
Information?
Find Nodes?
Leftovers?
Voting Booth?
My favorite model of computation is ...

Results (183 votes). Check out past polls.