I first approached this by forming a "flattened" intermediate hash where the first and second level keys were joined with a NUL character. The keys of the new hash could then be sorted by the associated descending numeric values then used for the printf statement. This code
use strict;
use warnings;
my %hoh_test = (
foo1 => { bar => -0.12697, baz => -0.000398154, },
foo2 => { bar => -4.0183e-05, baz => 0, },
foo3 => { bar => 9.966003977e-06, baz => 0.0001939, },
);
my %flatter =
map {
my $k1 = $_;
map {
join( qq{\0}, $k1, $_ ), $hoh_test{ $k1 }->{ $_ }
}
keys %{ $hoh_test{ $k1 } };
}
keys %hoh_test;
my @sortedKeys =
sort { $flatter{ $b } <=> $flatter{ $a } }
keys %flatter;
printf qq{foo: %s, ba: %s, value: %s\n},
split( m{\0}, $_ ), $flatter{ $_ }
for @sortedKeys;
produces
foo: foo3, ba: baz, value: 0.0001939
foo: foo3, ba: bar, value: 9.966003977e-06
foo: foo2, ba: baz, value: 0
foo: foo2, ba: bar, value: -4.0183e-05
foo: foo1, ba: baz, value: -0.000398154
foo: foo1, ba: bar, value: -0.12697
This seemed a bit long-winded so I thought it might be possible to still use combined keys but mapping out array refs to perform an ST all in one fell swoop. This code
use strict;
use warnings;
my %hoh_test = (
foo1 => { bar => -0.12697, baz => -0.000398154, },
foo2 => { bar => -4.0183e-05, baz => 0, },
foo3 => { bar => 9.966003977e-06, baz => 0.0001939, },
);
printf qq{foo: %s, ba: %s, value: %s\n}, @{ $_ } for
map { [ split( m{\0}, $_->[ 0 ] ), $_->[ 1 ] ] }
sort { $b->[ 1 ] <=> $a->[ 1 ] }
map {
my $k1 = $_;
map {
[ join( qq{\0}, $k1, $_ ), $hoh_test{ $k1 }->{ $_ } ]
}
keys %{ $hoh_test{ $k1 } };
}
keys %hoh_test;
produces identical output. I hope this is of interest.
Update: Corrected typo, s/tha/the/