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

When I run this code:
%foo =( '11' =>{ '4'=>'Four', }, '33' =>{ '1'=>'One', }, '2' =>{ '2' => 'Two', }, ); my $ref_HoH = \%foo; for my $k ( sort {%{ $ref_HoH{$a} } <=> %{ $ref_HoH{$b} } }keys + %$ref_HoH ) { print "$k\n"; for my $j ( sort keys %{$ref_HoH->{ $k }} ) { print "\t$j\n"; } }
I get this:
33 1 11 4 2 2
What should I do to get this code to print my keys like so:
2 11 33
Thank you guys.

Replies are listed 'Best First'.
Re: Sorting a Hash of Hashes
by McDarren (Abbot) on Jul 09, 2006 at 02:35 UTC
    You are over-complicating things.
    To print the keys of your hash, sorted numerically - all you need to do is:
    for (sort {$a <=> $b} keys %foo) { print "$_\n"; }

    Update: - to more directly answer your question, you need to change this line:

    for my $k ( sort {%{ $ref_HoH{$a} } <=> %{ $ref_HoH{$b} } }keys %$r +ef_HoH ) {
    ..to read like this:
    for my $k (sort {$a <=> $b } keys %$ref_HoH) {

    Cheers,
    Darren :)

Re: Sorting a Hash of Hashes
by HuckinFappy (Pilgrim) on Jul 09, 2006 at 03:01 UTC
    Let's look at what you're doing here (slightly reformatted):
    %foo = ( 11 =>{ 4 => 'Four' }, 33 =>{ 1 => 'One' }, 2 =>{ 2 => 'Two' } ); my $ref_HoH = \%foo; for my $k ( sort { %{ $ref_HoH{$a} } <=> %{ $ref_HoH{$b} } } keys %$ref_HoH ) { ... }
    Your sort routine is sorting on the values of each hash entry. That means you're sorting by memory address, since the value of each entry is an anonymous hash, so you are looking at the addresses of each anonymous hash.

    All you really need is to simplify the sort (Hey, make it simple, what good news!)

    use strict; use warnings; my %foo = ( 11 => { '4'=>'Four', }, 33 => { '1'=>'One', }, 2 => { '2' => 'Two', }, ); my $ref_HoH = \%foo; for my $k ( sort { $a <=> $b } keys %$ref_HoH ) { print "$k\n"; }
    hf@flux[30] perl /tmp/testit 2 11 33
    I'll leave the rest as an exercise for the OP.

    ~Jeff

Re: Sorting a Hash of Hashes
by Hue-Bond (Priest) on Jul 09, 2006 at 03:08 UTC

    McDarren's response is probably correct but, just to elaborate further...

    The first thing you should note is that your sorting hashes, that is, they're being demoted to mere scalars in order to be sorted. The scalar representation of a hash is a rather useless value that shows some internal statistics about the hash. Consider this code:

    my %foo =( '11' =>{ '4'=>'Four', }, '33' =>{ '1'=>'One', }, '2' =>{ '2' => 'Two', }, ); my $ref_HoH = \%foo; my @sorted = sort { my $c = %{ $ref_HoH->{$a} }; my $d = %{ $ref_HoH->{$b} }; print "comparing $c to $d...\n"; $c <=> $d; } keys %$ref_HoH; __END__ comparing 1/8 to 1/8... comparing 1/8 to 1/8... comparing 1/8 to 1/8...

    See what's happening? (Also note that I've fixed your incorrect usage of the reference; under warnings you would also had spotted the error). You seem to want to sort by the keys or the values of the inner hashes. In fact the order you want is also the one you'd get if you sorted the inner values reverse-alphabetically. But that isn't clear in your post.

    --
    David Serrano

Re: Sorting a Hash of Hashes
by johngg (Canon) on Jul 09, 2006 at 12:14 UTC
    Other Monks have already provided you with the answer to your problem. However, it might save you a little typing and also save entries in the symbol table if you set up your $ref_HoH directly using the curly brace anonymous hash constructor, like this

    my $ref_HoH = { 11 => { 4 => 'Four', }, 33 => { 1 => 'One', }, 2 => { 2 => 'Two', }, };

    Note also that you don't need to quote your hash keys (unless they contain spaces) when using the => (fat comma).

    Cheers,

    JohnGG

      You guys rock! Thanks so much for the replies. I am all for simplicity. I was a little confused following the code in the cookbook in Programming Perl.