Beefy Boxes and Bandwidth Generously Provided by pair Networks
P is for Practical

Comparing Hash's key to an <STDIN> and print it's corresponding value

by xxArwaxx (Novice)
on Apr 05, 2011 at 18:13 UTC ( #897573=perlquestion: print w/replies, xml ) Need Help??
xxArwaxx has asked for the wisdom of the Perl Monks concerning the following question:

Hello there! this is Arwa a newbie in Perl, I'v just started studying it on my own couple of months ago! so here I'm learning about hashes and couple of days ago I created a scenario where there's this fixed set of key-value pairs where I want to acquire the name from the user through STDIN and then compare that name with the set of keys I've within the hash and finally print the corresponding value(which is the family name for that person/key)! what happens actually when I run this script is nothing! so I was thinking if the comparing or the loop has already took place or not! so here's my code, I'd really love to hear what do you think of this guys!

my %family_name = ( "Alis" => "Williams", "Sara" => "McAwesome", "Serena" => "Anderson", ); my $key = keys %family_name; my $value = values %family_name; print "Enter a name to print it's family name : \n"; chomp(my $name= <STDIN>); foreach my $key1 (sort keys %family_name) { if ($name eq $key1) { print "$key1 is already there, and its family name is $family_name{$ +key1} "; } }
  • Comment on Comparing Hash's key to an <STDIN> and print it's corresponding value
  • Download Code

Replies are listed 'Best First'.
Re: Comparing Hash's key to an <STDIN> and print it's corresponding value
by kennethk (Abbot) on Apr 05, 2011 at 18:22 UTC
    Your code executes just fine for me; specifically I get:

    user@localhost:~/sandbox$ perl Enter a name to print it's family name : Alis Alis is already there, and its family name is Williams user@localhost: +~/sandbox$

    How are you attempting to interact with it?

    On a side note, hashes are wonderful tools, but you are not using them to their greatest advantage. To quote a great man:

    Doing linear scans over an associative array is like trying to club someone to death with a loaded Uzi. -- TimToady

    Rather than what you've written, I would use code more like:

    #!/usr/bin/perl -w use strict; my %family_name = ( "Alis" => "Williams", "Sara" => "McAwesome", "Serena" => "Anderson", ); print "Enter a name to print it's family name : \n"; chomp(my $name= <STDIN>); if (exists $family_name{$name}) { print "$name is already there, and its family name is $family_name +{$name} "; } else { print "I don't know anyone by the name $name\n"; }

    See exists for info on the exists function and perldata for info on what data types (including hashes) Perl has to offer.

      I guess you can blame it on me working on Padre at home, the Perl editor for Mac OS, while at work, I use the EngInSite editor for Win machines, it happens that in Padre, it only generates the errors but when done fixing them, it runs NOTHING! I noticed that only if there's a line with an <STDIN> ! so I'd run it from the Terminal instead, the old fashion way of running a Perl script! that quote is just a great piece of advice to keep in mind in future programming practice! I also loved the alternative solution you've provided! represents efficiency and simplicity all together at the same time! thanks for the reply!
Re: Comparing Hash's key to an <STDIN> and print it's corresponding value
by wind (Priest) on Apr 05, 2011 at 18:25 UTC

    Your code works fine, although you do create two variables $key and $value that you don't use or need.

    Also, a simpler test than looping on the keys is to just test if the key exists in the hash:

    use strict; use warnings; my %family_name = ( "Alis" => "Williams", "Sara" => "McAwesome", "Serena" => "Anderson", ); print "Enter a name to print it's family name : \n"; chomp(my $name = <STDIN>); if ($family_name{$name}) { print "$name is already there, and its family name is $family_name +{$name} "; }
      totally agree! both values are not needed, I forgot to remove them while modifying the same file to create different scenarios! I believe in your alternative solution, the if condition works the same as 'exist' the return value from that is 1 when the key is actually found, and 0 if not. hence, it would print the equivalent value for that particular key if it exists! correct me if I'm wrong! thanks for the reply my friend!
Re: Comparing Hash's key to an <STDIN> and print it's corresponding value
by biohisham (Priest) on Apr 05, 2011 at 20:43 UTC
    In addition to kennethk and wind valuable input, I have the following comments about your code...
    • LOOPING: in arrays, a scenario for looping is when we don't have prior information about what index position an array element resides in for us to readily reach it, on the other hand in hashes, (associative arrays is another name), the keys are the indices, so you basically were retrieving a certain hash value based on whether the index for that value exists within the hash or not, so in this context looping wasn't a necessary thing at all since each key is associated with a value..
    • CONTEXT: The context where you used the functions 'keys' and 'values' is a scalar context, so it returns to you only the number of keys and the number of values respectively and assigns that to $key and $val , if you assigned the outcome of these functions to arrays you'd have returned the actual hash keys and hash values themselves. Read Context tutorial from the Tutorials section
    • Finally; from your code, "$key1 is already there, and its family name is $family_name{$key1} ", replace 'its' by 'her'
    #Consider the output of the following my %family_name = ( "Alis" => "Williams", "Sara" => "McAwesome", "Serena" => "Anderson", ); my $key = keys %family_name; print $key; print "\n"; my $val = values %family_name; print $val; print "\n"; my @keys = keys %family_name; print "@keys\n"; my @values = values %family_name; print "@values\n";
    So, availing of the context property in Perl we can achieve what you sought in a TIMTOWTDI yet somewhat convoluted manner. Just as a proof of concept and maybe a review of some of the things you have studies so far consider the following code... Comments are duly provided
    use strict; use warnings; #The hash is populated as in the OP code above #The user is prompted to enter a name my @keys = keys %family_name; my @values = values %family_name; #The arrays members are in the same order the hash #is stored in the memory and not necessarily the #order in which the hash has been populated. my $index; for(my $i = 0; $i<=$#keys; $i++){ #looping through @keys if($name eq $keys[$i]){ $index = $i; #to retain the iterator value to $index retHashVal($name, $index); } } sub retHashVal{ my ($n,$i) = @_; print "$n is already there and her family name is $values[$i]\ +n"; }

    Excellence is an Endeavor of Persistence. A Year-Old Monk :D .
      wow! for a first reply, it's pretty much impressive how much I'm benefiting from these brain storming, in both, Perl and grammatical sense! :P well, I was like "what if the person is he, then what if he is a she" then I thought of replacing it with an "it" for time saving purposes as my main concern was actually running the code! lol I totally agree with what you just mentioned, because I've been in the situation of printing the number of elements there and not only once but in the same number as key-value pairs was there! after fixing it, I can understand the context concept you're talking about! I understood it even more, from the latter example you proposed! loved how you made use of arrays to print the index of the key that has been entered by the user, and then printing it's value! what's interesting even more in your code and might need a bit of elaboration, if you don't mind me, is that part when you invoke the retHashVal and both parameters are scalars, while in it's body you would use the array's default variable in assigning to $n and $i .. how things are working there? depending on context I'd say that @_ would be converted implicitly to a scalar, is this how it goes in this case?

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://897573]
Approved by kennethk
[Corion]: Heh. Highly confusing. I use /qr in my web app as an entry point to generate QR code images. So in my code I now have '/qr/:name/:key' - "But why would I single-quote a malformed regular expression?!" ;-)
[Corion]: Also, I need to decide on whether to do the user management in SQLite or do it in a JSON structure instead...
[Happy-the-monk]: NodeReaper: that would have to go uphill.

How do I use this? | Other CB clients
Other Users?
Others browsing the Monastery: (8)
As of 2018-03-19 12:41 GMT
Find Nodes?
    Voting Booth?
    When I think of a mole I think of:

    Results (240 votes). Check out past polls.