No such thing as a small change PerlMonks

### 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?
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others chanting in the Monastery: (1)
As of 2018-04-20 07:59 GMT
Sections?
Information?
Find Nodes?
Leftovers?
Voting Booth?
My travels bear the most uncanny semblance to ...

Results (75 votes). Check out past polls.

Notices?