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

Dear Monks, How can I sort HoH according to values and then print out the results? $HoH{www}{wwe}=1; $HoH{www}{wte}=2; $HoH{www}{wee}=0;

Replies are listed 'Best First'.
Re: how to sort HoH according to value
by Tanktalus (Canon) on Jun 18, 2008 at 23:38 UTC

    You don't exactly tell us what you're expecting for output... nor is your example values enough to indicate certain behaviours even if you were to give us the output for the above HoH.

    I'm going to take a quick guess:

    #!/usr/bin/perl use strict; use warnings; my %HoH = ( www => { wwe => 1, wte => 2, wee => 0} ); for my $outter (sort keys %HoH) { for my $inner (sort { $HoH{$outter}{$a} <=> $HoH{$outter}{$b} } ke +ys %{$HoH{$outter}}) { print "${outter}::$inner = $HoH{$outter}{$inner}\n"; } }
    producing:
    $ perl ./x.pl www::wee = 0 www::wwe = 1 www::wte = 2
    Probably not entirely what you want, but I can't be sure.

    Update: Probably closer to what you want:

    #!/usr/bin/perl use strict; use warnings; my %HoH = ( www => { wwe => 11, wte => 21, wee => 0}, zzz => { zze => 15 }, ); my @keys = sort { $HoH{$a->[0]}{$a->[1]} <=> $HoH{$b->[0]}{$b->[1]} } map { my $outter = $_; map { [ $outter, $_ ] } keys %{$HoH{$outter}}; } keys %HoH; for (@keys) { print( (join '::', @$_), ' = ', $HoH{$_->[0]}{$_->[1]}, "\n"); }
    which produces:
    $ perl ./x.pl www::wee = 0 www::wwe = 11 zzz::zze = 15 www::wte = 21
    I'm sure one of the other monks has a more generic solution here (probably either TheDamian or Merlyn) for handling arbitrary depths...

      I would like to sort these values according to numbers, with disrespect to the key values. $HoH{ss}{1}=23; $HoH{s2}{2}=1; $HoH{ss}{3}=44; After sorting: $HoH{ss}{3}=44; $HoH{ss}{1}=23; $HoH{s2}{2}=1;
        I don' know if you meant it, but your "before" and "after" descriptions of the hash are exactly the same.

        Are you describing the order in which you want to display the values of the hash?

Re: how to sort HoH according to value
by sgifford (Prior) on Jun 19, 2008 at 02:28 UTC
    sovixi,

    The key thing to realize here is that a hash doesn't have any notion of order. The most straightforward solution is to copy the information you want from the hash into a list, which is ordered, then sort the list. For example:

    # Convert HoH into a list of arrayrefs: [value, key1, key2, ...] my @list; while (my($k1,$v1) = each(%HoH)) { while (my($k2,$v2) = each(%$v1)) { push @list, [$v2, $k1, $k2]; } } # Sort the list by its first element @list = sort { $a->[0] <=> $b->[0] } @list; # Now print the list foreach my $elt (@list) { print "@$elt\n"; }
Re: how to sort HoH according to value
by psini (Deacon) on Jun 19, 2008 at 09:35 UTC

    You asked the same question, in exactly the same words, three weeks ago. Why do you expect we worked on your problem if you did nothing on it in this time?

    What about the answers you got then? Had you tried them? What have you got? Quo usque tandem abutere, sovixi, patientia nostra?

    Careful with that hash Eugene.