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

All If i have the following hash of hashes
my %file_attachments = ( '1 => { 'price' => '10.00', 'desc' => 'the 1st test'}, '2' => { 'price' => '12.00', 'desc' => 'the 2nd test'}, '3' => { 'price' => '13.00', 'desc' => 'the 3rd test'}, '4' => { 'price' => '14.00', 'desc' => 'the 4th test'} );
What would be the best way to loop over it and say So a counter will hold the number of elements in the hash so my $count = 4; then i just want to loop over each without knowing the key or key values

Replies are listed 'Best First'.
Re: Looping through hash of hashes
by GrandFather (Saint) on Nov 26, 2005 at 10:44 UTC

    The general technique used is of the form for my $key (sort keys %hash) {...}. You need the sort if sorted order is important. In general you get the keys back in some arbitary order which is neither inserted or sorted order.

    $key is used to access the file information: file_attachments{$key}. You then need to retreive the individual fields as: file_attachments{$key}{'price'} etc.


    DWIM is Perl's answer to Gödel
Re: Looping through hash of hashes
by TedPride (Priest) on Nov 26, 2005 at 15:04 UTC
    The following should do what you want. Note that the sort is alphabetic instead of numerical - you may want to change to numerical if you know for a fact that all keys will be numbers.
    use strict; use warnings; my $p; my %file_attachments = ( '1' => { 'price' => '10.00', 'desc' => 'the 1st test'}, '2' => { 'price' => '12.00', 'desc' => 'the 2nd test'}, '3' => { 'price' => '13.00', 'desc' => 'the 3rd test'}, '4' => { '' => '', '35' => 'D', '11' => '3104052', '63' => '0', '167' => 'FUT', '200' => '200512', '1' => '2', '44' => '112.55', '55' => 'XEURFGBM0F2005Z', '50' => 'portwaretrader1', '40' => '2', '57' => 'RISKGATEWAY', '15' => 'USD', '38' => '1', '52' => '20051118-07:31:46', '59' => '0', '60' => '20051118-07:31:40', '34' => '37', '56' => 'EXLINK_CAMPBELL', '49' => 'CAMPBELL_EXLINK', '10' => '170', '54' => '1' } ); for (sort keys %file_attachments) { print "'$_' =>\n"; $p = $file_attachments{$_}; print " '$_' => '$p->{$_}'\n" for sort keys %$p; print "\n"; }
      Guys thanks for the help looks good..... :)
Re: Looping through hash of hashes
by tirwhan (Abbot) on Nov 26, 2005 at 10:47 UTC
    for my $file (sort keys %file_attachments) { print "$file, price=$file_attachments{$file}{price}, desc=$file_ +attachments{$file}{desc} "; }

    Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it. -- Brian W. Kernighan
      What if you did not know the names of the keys under the parent like the following. This was extracted from data dumper.
      $VAR1 = '4'; $VAR2 = { '' => '', '35' => 'D', '11' => '3104052', '63' => '0', '167' => 'FUT', '200' => '200512', '1' => '2', '44' => '112.55', '55' => 'XEURFGBM0F2005Z', '50' => 'portwaretrader1', '40' => '2', '57' => 'RISKGATEWAY', '15' => 'USD', '38' => '1', '52' => '20051118-07:31:46', '59' => '0', '60' => '20051118-07:31:40', '34' => '37', '56' => 'EXLINK_CAMPBELL', '49' => 'CAMPBELL_EXLINK', '10' => '170', '54' => '1' };
      So the parent keys are just numbers like 1.2.3.4.4.5.5 and i have a counter which holds how many keys are in the %messagebin hash, so what i want to be able to do is sort and process each key under the parent with the value.
      Something like
      for my $file (sort keys %messagebin) { #enter into key $messagebin{$file} then foreach my $key in the above print out $key = $value }
      Sorry does not make much sense.
        What if you did not know the names of the keys

        Then use the keys builtin to find them out. Something like this:

        for my $file (sort keys %messagebin) { print "File $file:\n"; # $messagebin{$file} is a hashref, so: my @subkeys = sort keys %{$messagebin{$file}}; foreach my $subkey (@subkeys) { print "\t$subkey = $messagebin{$file}{$subkey}\n"; } }

        "In adjectives, with the addition of inflectional endings, a changeable long vowel (Qamets or Tsere) in an open, propretonic syllable will reduce to Vocal Shewa. This type of change occurs when the open, pretonic syllable of the masculine singular adjective becomes propretonic with the addition of inflectional endings."  — Pratico & Van Pelt, BBHG, p68