Beefy Boxes and Bandwidth Generously Provided by pair Networks
Don't ask to ask, just ask

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.

Replies are listed 'Best First'.
Re: the if statement
by toolic (Bishop) 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 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 Wiggins (Hermit) 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.

    1 hash access, + possibly 1 scalar assignment

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

    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!

      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]$ ./ 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 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 Rate double assign double 121/s -- -0% assign 122/s 0% -- real 2m32.598s user 2m19.745s sys 0m6.498s [~]#
Re: the if statement
by kwn (Novice) on Sep 27, 2008 at 22:34 UTC
    Thanks guys, this helped me a lot.

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://714064]
Approved by toolic
[Corion]: (one of my scripts simply catches high amounts and I phone people making that trade, ideally before the payment is due)
[Corion]: The sad thing is that my script sits at the end of the pipeline and can only look at the payments due today or tomorrow basically, while there are many more systems further up in the pipeline
[GotToBTru]: better late than never, I guess
[Corion]: GotToBTru: Sure - there is a long and sad story of many frantic cleanups that led us to implement this notification ;)

How do I use this? | Other CB clients
Other Users?
Others musing on the Monastery: (10)
As of 2017-03-29 11:34 GMT
Find Nodes?
    Voting Booth?
    Should Pluto Get Its Planethood Back?

    Results (347 votes). Check out past polls.