Beefy Boxes and Bandwidth Generously Provided by pair Networks
Don't ask to ask, just ask
 
PerlMonks  

hash of hashes

by Anonymous Monk
on Oct 06, 2013 at 03:21 UTC ( #1057100=perlquestion: print w/ replies, xml ) Need Help??
Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

in a file1 i have statements like
-------------------------
strawberry red green rose
apple red rose
mango green
-------------------------
i want to convert this as
-------------------------
red strawberry apple
green strawberry mango
rose strawberry apple
-------------------------
and write the result in another file2.some said we have to use hash of hashes.i am new to perl.please any one help me!!

Comment on hash of hashes
Re: hash of hashes
by davido (Archbishop) on Oct 06, 2013 at 03:28 UTC

    What rules are you using to make the conversion?


    Dave

      Excellent question. Looking forward to the answer from OP.

      Looks to me like the format for file 1 is:

      {fruit} { {color 1} {...color n} }

      It looks like the format for file 2 is:

      {color} { {fruit 1} {...fruit n} }

      But that's just a guess, of course. :-)

Re: hash of hashes
by marinersk (Chaplain) on Oct 06, 2013 at 03:34 UTC
    Okay, so you need:
    1. Some code to read file1;
    2. Some code to store its data into hashes;
    3. Some code to write file2.

    Hash of Hashes can be a bit complicated the first time you try them, can even be intimidating.

    But surely if you are trying to do Hash of Hashes, you have long since learned how to read and write files, yes?

    So, in keeping with How do I post a question effectively?, why don't you show us what you have thus far, and let us guide you through the changes needed to dive into these potentially intimidating (but eventually easy to use) Hash of Hashes?

      #!/usr/local/bin/perl open (MYFILE, 'test1.txt'); while (<MYFILE>) { chomp; print "$_\n"; @line = split /[\s]+/; 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"; } for my $key (keys %hash) { my $array = $hash{$key}; print "$_ $key, " ; # print $hash{$key}; # print "$_ $key, "; # foreach $x(keys %hash) # { # print $hash{$x} ; # } } } close (MYFILE);

      i am not an expert but i tried like this my logic not correct for handling hash of hashes.

        $hash{$d}{$i}=$line[$i];

        At this point in the code,  $d is a fruit,  $i is an index (a number), and  $line[$i] is a color (AFAIU your code). Why would you want to associate a number with a fruit and a color with a number (perhaps better expressed as) a fruit with a number and a number with a color? Please take a look at Re^3: hash of hashes.

        Also, try using Data::Dumper or Data::Dump (my favorite) for looking at data structures — much more convenient.

        And again, please take a look at perldsc.

        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:
         

        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.

Re: hash of hashes
by marinersk (Chaplain) on Oct 06, 2013 at 03:43 UTC
    If it will help you, a sample of Hash of Hashes:
    my %hash = (); $hash{'jeep'}{'wrangler'} = 1; $hash{'jeep'}{'liberty'} = 1; $hash{'ford'}{'pinto'} = 1; $hash{'ford'}{'taurus'} = 1;

    You can use Data::Dumper to see what %hash looks like, and probably it will help you understand hash of hashes better.

      can you suggest the logic how can i handle this situation using hash of hashes

        You seem to be pretty much at sea on this, so here's a bit of an elaboration on marinersk's approach. I'm assuming you can read "statements" from a file, get rid of newlines (see chomp), write data to a file, etc.

        >perl -wMstrict -le "use Data::Dumper; ;; my @statements = ( 'strawberry red green rose', 'apple red rose', 'mango green', ); ;; my %hash; for my $statement (@statements) { my ($fruit, @colors) = split m{\s+}xms, $statement; for my $color (@colors) { $hash{$fruit}{$color} = 1; } } ;; print Dumper \%hash; " $VAR1 = { 'mango' => { 'green' => 1 }, 'strawberry' => { 'rose' => 1, 'green' => 1, 'red' => 1 }, 'apple' => { 'rose' => 1, 'red' => 1 } };

        See perldsc for a discussion of techniques for iterating through a data structure of this (hash-of-hashes, HoH) or any other kind. As others have said, we would be happy to answer further questions, but the community really likes to see supporting work as well.

        Update: Also see Re: hash of hashes for a different, perhaps more directly expressive data structure.

Re: hash of hashes
by kcott (Abbot) on Oct 06, 2013 at 03:50 UTC

    You've provided no information regarding how this conversion is supposed to work. You've shown no indication that you've made any effort yourself.

    PerlMonks is not a free, code-writing service. See "Do Your Own Work" in How (Not) To Ask A Question.

    Please read "How do I post a question effectively?" to further understand the problems with what you've posted and for guidelines on how to compose a better question.

    Are you the same Anonymous Monk who authored the identically titled hash of hashes earlier today? The responses to that posting should provide further insight into these issues.

    -- Ken

Re: hash of hashes
by boftx (Chaplain) on Oct 06, 2013 at 05:06 UTC

    Not to be flip, but if you don't comprehend how a hash of whatever works then you will never grok Perl. Considering the body of work not only in the Monastery but in the wild overall it would appear you need to apply yourself a bit more before crying for help.

    On time, cheap, compliant with final specs. Pick two.
Re: hash of hashes
by NetWallah (Abbot) on Oct 06, 2013 at 05:13 UTC
    This is probably what you are looking for:
    use strict; my %byColor; while (<DATA>){ my ($fruit, @colors) = split; for my $c(@colors){ push @{ $byColor{$c} }, $fruit; } } for my $c(sort keys %byColor){ print "$c\t @{$byColor{$c}}\n"; } __DATA__ strawberry red green rose apple red rose mango green
    Output:
    green strawberry mango red strawberry apple rose strawberry apple

                 My goal ... to kill off the slow brain cells that are holding me back from synergizing my knowledge of vertically integrated mobile platforms in local cloud-based content management system datafication.

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://1057100]
Approved by marinersk
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others chilling in the Monastery: (6)
As of 2014-07-26 17:36 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    My favorite superfluous repetitious redundant duplicative phrase is:









    Results (178 votes), past polls