Beefy Boxes and Bandwidth Generously Provided by pair Networks
laziness, impatience, and hubris

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?

Replies are listed 'Best First'.
Re: Accessing hash values in a HOH
by Plankton (Vicar) 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


      16:53 >perl 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?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://1020274]
Approved by Plankton
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others meditating upon the Monastery: (5)
As of 2017-07-23 21:16 GMT
Find Nodes?
    Voting Booth?
    I came, I saw, I ...

    Results (347 votes). Check out past polls.