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

the if statement

by kwn (Novice)
on Sep 27, 2008 at 22:00 UTC ( #714064=perlquestion: print w/ replies, xml ) Need Help??
kwn has asked for the wisdom of the Perl Monks concerning the following question:

Im trying to write a statement: if users input = a key in %hash print the value of the key. This code doesnt work but shows something like:
%hash = (one => 'uno', two => 'dos', three => 'tres'); $input = <STDIN>; chomp $input; if ($input = (keys %hash)) { print the value that matches the key of %hash; }
So, if I type one at the prompt it should return with uno.

Comment on the if statement
Download Code
Re: the if statement
by FunkyMonk (Canon) on Sep 27, 2008 at 22:06 UTC
    You mean like this?
    my %hash = (one => 'uno', two => 'dos', three => 'tres'); my $input = <STDIN>; chomp $input; if (my $ans = $hash{$input}) { print "$input => $ans\n"; }

    Note that I've declared all the variables with my because I have strict (and warnings) enabled.


    Unless I state otherwise, all my code runs with strict and warnings
Re: the if statement
by broomduster (Priest) on Sep 27, 2008 at 22:11 UTC
    This looks like homework, so here are some hints.

    (keys %hash) is a list of the keys for %hash. The scalar assignment $input = (keys %hash) puts the number of keys into $input (which is probably not what you want to do). OTOH, to compare $input to each of the keys, you need to loop through the keys, comparing $input to each key. Since the keys (and the user input) are strings, you use eq to do the comparison.

    Updated: Scrub the stupidity; no need to check everything; this is a hash, after all.

      you need to loop through the keys, comparing $input to each key
      That's what exists is for. In this case if ($hash{$input}) { ... } is probably good enough.
Re: the if statement
by toolic (Chancellor) on Sep 27, 2008 at 22:12 UTC
    First, check for the existence of the hash key, then print the value of the hash key. Your "if" statement was performing an assignment and was probably always returning "true". Try this:
    %hash = (one => 'uno', two => 'dos', three => 'tres'); $input = <STDIN>; chomp $input; if (exists $hash{$input}) { print $hash{$input}, "\n"; }
Re: the if statement
by kwn (Novice) on Sep 27, 2008 at 22:34 UTC
    Thanks guys, this helped me a lot.
Re: the if statement
by Wiggins (Friar) on Sep 28, 2008 at 14:53 UTC
    The comments from FunkyMonk and toolic bring up a (possible) subtle difference in the "pattern",that I have always puzzled about.

    --FunkyMonk
    1 hash access, + possibly 1 scalar assignment

    if (my $ans = $hash{$input}) { print "$input => $ans\n";

    --toolic
    1 hash access + possibly 1 more hash access
    is the 1st result 'cached' and the second access reuses the 1st result?

    if (exists $hash{$input}) { print $hash{$input}, "\n";

      ???
    • Is there any efficiency advantage in either approach?
    • Does the hash size make a difference?
    • How about when done 5000 times for different $input values?
      In this particular case, the desired value is always 'true', but Funkymonk's soln would fail if it was 'false' eg 0 (zero) or undef.
      toolic's soln tells you there's a hash entry there, even if the associated value is 'false' or undef.
      :)
      • Is there any efficiency advantage in either approach?
      • Does the hash size make a difference?
      • How about when done 5000 times for different $input values?

      I personally believe that there's no significative advantage of one approach over the other but possibly in terms of personal tastes. As far as efficiency is concerned, what do you mean? Speed of execution? If so, then I wouldn't mind, since it's such a tiny difference, but you may answer your question(s) yourself with Benchmark.pm!

      I notoriously suck at benchmarks, doing continuous errors, (which are generally pointed out by others...) but here's my try anyway:

      As I expected, as it is it doesn't show any noticeable difference.

      kirk:~ [15:16:04]$ ./bm.pl Rate double assign double 29.4/s -- -1% assign 29.7/s 1% --

      Indeed I generally refrain from the temptation of doing benchmarks "like this" when someone suggests them, and even tend to slightly bash those who do: this time I was curious to see if at least a tiny systematic difference would have arisen, but that doesn't seem to be the case: feel free to modify it the way you like most though!

      --
      If you can't understand the incipit, then please check the IPB Campaign.
        I love your answer. Below I have put my result of running your benchmark in a Fedora9 VM on a Lenovo laptop.

        But what really intrigues me is how you built the test hash and keys to test with... 2 'map's in 2 lines of code. Figuring out 'genkeys' and the %hash, and @test values will take me the rest of the afternoon; thanks

        ### using 5.010 [~]# time perl hash_test_benchmark.pl Rate assign double assign 119/s -- -2% double 122/s 2% -- real 2m30.601s user 2m17.789s sys 0m6.317s ### without 5.010 [~]# time perl hash_test_benchmark.pl Rate double assign double 121/s -- -0% assign 122/s 0% -- real 2m32.598s user 2m19.745s sys 0m6.498s [~]#

Log In?
Username:
Password:

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

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

    How do you remember the number of days in each month?











    Results (91 votes), past polls