Beefy Boxes and Bandwidth Generously Provided by pair Networks
XP is just a number
 
PerlMonks  

hash with identical keys

by props (Hermit)
on Dec 06, 2007 at 22:06 UTC ( [id://655528]=perlquestion: print w/replies, xml ) Need Help??

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

Hi monks Iam trying to solve an exercise from the textbook Intermediate Perl (8.6.2). the following data is stored in a file named data.

Gilligan: 1 coconut

Skipper: 3 coconuts

Gilligan: 1 banana

Ginger: 2 papayas

Professor: 3 coconuts

MaryAnn: 2 papayas

I have to create for each name a respective file such as this gilligan.info with its fruit written in the file . Like gilligan.info must have written in it : Gilligan: 1 coconut Gilligan: 1 banana.

#my code: #this fails since two Gilligan keys exist use warnings; use strict; open( DATA, 'data' ) or die "i cannot read data:$!\n"; my %hash; while (<DATA>) { my ( $name, $item ) = split(/:/); $hash{$name} = $item; for my $name ( keys %hash ) { my $lc_name = lc $name; open( FILE, ">$lc_name.info" ) or die "cannot open FILE:$!\n"; print FILE "$name $hash{$name}"; } }

The trouble is that i shouldn't be using hash because there are 2 identical key entries(Gilligan). Now I've experimented with HoA with no luck some guidance is more than welcome

Replies are listed 'Best First'.
Re: hash with identical keys
by tuxz0r (Pilgrim) on Dec 06, 2007 at 22:20 UTC
    What about a HoH's, letting you store a count using the fruit as a key into a hash based on name, e.g.
    use Data::Dumper; my %islanders; while (<DATA>) { chomp; my ($key, $cnt, $fruit) = split / /; $key =~ s/://g; $islanders{$key}{$fruit} += $cnt; } print Dumper(\%islanders); __DATA__ Gilligan: 1 coconut Skipper: 3 coconuts Gilligan: 1 banana Ginger: 2 papayas Professor: 3 coconuts MaryAnn: 2 papayas
    I think this approach could work equally as well? Yielding, ...
    $VAR1 = { 'Ginger' => { 'papayas' => '2' }, 'Gilligan' => { 'banana' => '1', 'coconut' => '1' }, 'Skipper' => { 'coconuts' => '3' }, 'MaryAnn' => { 'papayas' => '2' }, 'Professor' => { 'coconuts' => '3' } };

    ---
    s;;:<).>|\;\;_>?\\^0<|=!]=,|{\$/.'>|<?.|/"&?=#!>%\$|#/\$%{};;y;,'} -/:-@[-`{-};,'}`-{/" -;;s;;$_;see;
    Warning: Any code posted by tuxz0r is untested, unless otherwise stated, and is used at your own risk.

      Hi Monks this is my code and it works. I ended up using the sub because of the many "explicit package name" errors . Is there a way to avoid the sub ?
      use warnings; use strict; use Data::Dumper; sub foo { my %hash = (); while (<DATA>) { chomp; my ( $name, $cnt, $item ) = split / /; $name =~ s/://g; $hash{$name}{$item} += $cnt; } return \%hash; } my $rhash = foo(); for my $k1 ( sort keys %$rhash ) { for my $k2 ( sort keys %{ $rhash->{$k1} } ) { open( FILE, ">>$k1.info" ); print FILE " $k1: $rhash->{$k1}{$k2} $k2 \n"; } } __DATA__ Gilligan: 1 coconut Skipper: 3 coconuts Gilligan: 1 banana Ginger: 2 papayas Professor: 3 coconuts MaryAnn: 2 papayas
Re: hash with identical keys
by moritz (Cardinal) on Dec 06, 2007 at 22:09 UTC
    A hash of arrays is the right approach:
    push @{$hash{$name}}, $item;
Re: hash with identical keys
by brian_d_foy (Abbot) on Dec 07, 2007 at 02:14 UTC

    This exercise comes from the filehandle reference chapter. You're supposed to open files for each character and write to the correct file when you encounter a line of input. The hint from the end of the exercise is:

    Hint: use a hash, keyed by the castaway name, holding IO::File objects for each output file. Create them as necessary.

    The hash is for the filehandles, not the data. Give it another go, and if you need more of a hint, peek at the exercise answer. Good luck :)

    --
    brian d foy <brian@stonehenge.com>
    Subscribe to The Perl Review
Re: hash with identical keys
by aquarium (Curate) on Dec 06, 2007 at 22:30 UTC
    you don't need a data structure at all. upon reading each entry open the file (for append) named in column one of the entry, write the entry and close it. loop. this assumes that you don't need to add up entries of the same fruit for a particular character.
    the hardest line to type correctly is: stty erase ^H

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others goofing around in the Monastery: (1)
As of 2024-04-25 04:14 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found