Thank you for showing your code -- I see where you lost your way. In the "read more" link below, I'll cover all the stuff you need to fix.

Since this looks like homework, I want you to understand what needs to be fixed, not just hand you working code and leave you lost when your next assignment builds on this one.

I made the changes discussed under the "Read more" link below. Then I adjusted some of the print statements so they had newlines and indentation differently than you had been doing.

This is what happened when I did that to your script:

C:\Steve\Dev\PerlMonks\P-2013-10-06@2342-Hash-Of-Hashes>FruitColor1b.p +l strawberry red green rose red Added hash{red}{strawberry} green Added hash{green}{strawberry} rose Added hash{rose}{strawberry} apple red rose red Added hash{red}{apple} rose Added hash{rose}{apple} mango green green Added hash{green}{mango} -----[ Results ]--------------- key = 'rose' subkey = 'strawberry' key = 'rose' subkey = 'apple' key = 'green' subkey = 'mango' key = 'green' subkey = 'strawberry' key = 'red' subkey = 'strawberry' key = 'red' subkey = 'apple'

Do I have your attention now? :-). Then let's get to it:
 

  1. Your code is missing two critical lines. Never ever ever ever forget them, as they will help you time and time and time again:
    use strict; use warnings;
    And since you are using strict now, you will need to pre-declare your hash:
    my %hash = ();
    Chafe not -- this is a good thing. Please just trust me on this.
     
  2. @line = split /[\s]+/;

    Nice use of split. Let's fix a few things.

    1. You don't need the brackets since you are only capturing splitting on one kind of character;
    2. Look ahead. You have a line with a fruit and a bunch of colors.

    So try this instead:

    my ($fruit, @colors) = split /\s+/;

    This way we pull out the fruit and the array of colors in one fell swoop.

    Admit it -- Perl is kinda' neat, isn't it? :-)
     

  3. for ($i = 1;$i <= $#line;$i++) { $d=$line[0]; print "$d"; # $d[$k++]=$line[$i],1; $hash{$d}{$i}=$line[$i]; print "$hash{$d}{$i}\n"; }

    1. You are doing the loop the hard way. Let Perl do the work for you.
    2. You came close on the hash -- closer than you might think.

      What you almost ended up with is something like:

      {apple}{1} = 'red' {apple}{2} = 'green'
      What you wanted was more like:
      {apple}{red} {apple}{green}
    So try something like this:
    foreach my $color (@colors) # Was: for ($i = 1;$i <= $ +#line;$i++) { $hash{$color}{$fruit} = 1; # Was: $hash{$d}{$i}=$line +[$i]; print "Added hash{$color}{$fruit}\n"; # Was: print "$hash{$d}{$i +}\n"; }
    The '1' doesn't really mean anything. We just need to put a value into that slot in the Hash of Hashes. That way, later, when we look through the keys of the hash, there's something there to find.

    Ironically, the value isn't what we're after. It's the organization of the keys.

    More Perl goodness. :-)
     

  4. You need to loop through the whole input file before trying to process the hash.

    You had this at the bottom of your code:

    } close (MYFILE);
    Move it up so it is right after the foreach loop we just discussed.
     
  5. Now you need to process the Hash of Hashes you built.

    This one I'm just going to hand to you, since the syntax isn't particularly intuitive at first. But learn this stuff -- most notably, you should really disassemble the inner foreach loop until you understand it. You won't believe how often it will help you take easy shortcuts in Perl later.

    foreach my $key (keys %hash) { # -----[ Here is how you read a Hash of Hashes ]--------------- foreach my $subkey (keys %{$hash{$key}}) # Was: my $array = +$hash{$key}; { print "key = '$key' subkey = '$subkey'\n"; } }

     
  6. Once you incorporate these changes into your script, it should become fairly obvious how to write your output file -- which you will do in place of the generic print statement I just handed you.

Holler with any questions. The more you understand this, the more of Perl's innate power you are going to be able to unleash at will.


In reply to Re^3: hash of hashes by marinersk
in thread hash of hashes by Anonymous Monk

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.