in reply to help sorting hash of hashes by value
If I read your code correctly, only the inner loop on $ba is sorting on values. Hash keys are not returned in a specific order, so your $foo keys may be all over the place. But your expected output really looks to be sorting on key $foo, then on $ba, so I'm not sure "sorting on values" is you are asking. If it is, I would expect the following code snippet to generate your expected output:
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, }, ); # Sort on $foo decending foreach my $foo ( sort { $b cmp $a } keys %hoh_test ) { # Sort on values decending foreach my $ba ( sort { $hoh_test{$foo}{$b} <=> $hoh_test{$foo}{$a} } keys %{$hoh_test{$foo}} ) { printf "foo: %s, ba: %s, value: %s\n", $foo, $ba, $hoh_test{$foo}{$ba}; } }
The output matches your expected output:
$ perl 111142758a.pl 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
If instead you are sorting on $foo decending then on $ba decending, the code would instead be:
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, }, ); # Sort on $foo decending foreach my $foo ( sort { $b cmp $a } keys %hoh_test ) { # Sort on $ba decending foreach my $ba ( sort { $b cmp $a } keys %{$hoh_test{$foo}} ) { printf "foo: %s, ba: %s, value: %s\n", $foo, $ba, $hoh_test{$foo}{$ba}; } }
This output also matches your expected output:
$ perl 111142758b.pl 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
If you really want your hash output sorted by values, there may be other ways but the simplest that comes to my mind is to push the order into a temporary structure you can actually sort:
use strict; use warnings; use utf8; 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, }, ); # Sort on values by pushing into an intermediary structure my @ordering; foreach my $foo ( keys %hoh_test ) { foreach my $ba ( keys %{ $hoh_test{$foo} } ) { push @ordering, { foo => $foo, ba => $ba, v => $hoh_test{$foo} +{$ba}, }; } } # Sort intermediary structure on value (v) from above. foreach my $i ( sort { $ordering[$b]{v} <=> $ordering[$a]{v} } 0 .. $# +ordering ) { printf "foo: %s, ba: %s, value: %s\n", $ordering[$i]{foo}, $ordering[$i]{ba}, $ordering[$i]{v}; }
This also creates your expected output:
$ perl 111142758c.pl 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
Hope that helps.
|
---|