Beefy Boxes and Bandwidth Generously Provided by pair Networks Joe
Just another Perl shrine
 
PerlMonks  

Accessing hash values in a HOH

by modi2020 (Novice)
on Feb 23, 2013 at 05:34 UTC ( #1020274=perlquestion: print w/ replies, xml ) Need Help??
modi2020 has asked for the wisdom of the Perl Monks concerning the following question:

Hi guys, In the example below I create a hash with names as values and phone numbers as keys:

my % phoneDirectory=( ‘Shirly’=>‘7267975’, ‘Michael’=>‘5243755’, ‘Fred’=>‘1294874’, );
I can extract the phone number of say Shirly by phoneNumber=$phoneDirectory{"Shirly"}; What if Shirly had more than one number. Is there a way to extract all her phone numbers by using her name as a key? Now,Suppose I have the following file:
John Marry John Lea John Paul David Patrik David Sam
I want to be able to read the file into a has of hash and I want to be able to retrieve all elements under a key. For example I want to be able to say print $hash{John} and get Marry, Lea, Paul. Is that possible?

Comment on Accessing hash values in a HOH
Select or Download Code
Re: Accessing hash values in a HOH
by Plankton (Priest) on Feb 23, 2013 at 05:46 UTC
Re: Accessing hash values in a HOH
by space_monk (Chaplain) on Feb 23, 2013 at 06:34 UTC
    As previous poster has indicated, a hash of arrays appears to be what you want....
    my % phoneDirectory=( 'Shirley'=> [ '555-0001', '555-0002' ], 'Michael' => [ ‘555-MIKE' ], 'Fred' => [ '555-FRED'] ); #access numbers for Shirley say $_ for @{$hash{'Shirley'}};
    As to your second question, something like:
    my %names; while (<>) { my ($first, $last) = split; if ($last) { # add last name to hash element push @{$names{$first}}, $last; } } # print names print @{$names{'John'}};

    Caveat: Just taking a break from XCOM, have not compiled or tested above, so send me a message if syntax not quite right and I'll fix it :-)

    Updated with comments from Athanasius below..

    A Monk aims to give answers to those who have none, and to learn from those who know more.

      A couple of points:

      1. Don’t use first as the name of both the hash and the scalar! Yes, Perl can easily disambiguate them, but why make things harder (for humans) to read and comprehend than they need to be?

      2. The line:

        $first{$first} = [] if (!$first{$first});

        isn’t needed — autovivification will take care of that for you automatically.

      #! perl use strict; use warnings; my %names; while (<DATA>) { my ($first, $last) = split; push @{$names{$first}}, $last if $last; } my $name_to_find = 'John'; print "$name_to_find --> ", join(', ', @{$names{$name_to_find}}), "\n" +; __DATA__ John Marry John Lea John Paul David Patrik David Sam

      Output:

      16:53 >perl 545_SoPW.pl John --> Marry, Lea, Paul 16:56 >

      Hope that helps,

      Athanasius <°(((><contra mundum Iustus alius egestas vitae, eros Piratica,

      Thank you so much! Worked like charm! Best wishes

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others examining the Monastery: (4)
As of 2014-04-19 21:24 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    April first is:







    Results (483 votes), past polls