How to test if a value exist in a hash?
Shorter answer using smart match (Perl version 5.10 or later):
print 2 ~~ [values %x];
Fundamentally, a hash is a data structure optimized for solving the converse question, knowing whether the key 2 is present. But it's hard to judge without knowing, so let's assume that won't change.
Possibilities presented here will depend on:
- how often you need to do it
- how dynamic the hash is
One-time op
grep $_==2, values %x
(also spelledgrep {$_==1} values %x
) will return a list of as many 2s as are present in the hash, or, in scalar context, the number of matches. Evaluated as a boolean in a condition, it yields just what you want.grep
works on versions of Perl as old as I can remember.use List::Util qw(first); first {$_==2} values %x
returns only the first match,undef
if none. That makes it faster, as it will short-circuit (stop examining elements) as soon as it succeeds. This isn't a problem for 2, but take care that the returned element doesn't necessarily evaluate to boolean true. Usedefined
in those cases.List::Util
is a part of the Perl core since 5.8.use List::MoreUtils qw(any); any {$_==2} values %x
returns exactly the information you requested as a boolean, and exhibits the short-circuiting behavior.List::MoreUtils
is available from CPAN.2 ~~ [values %x]
returns exactly the information you requested as a boolean, and exhibits the short-circuiting behavior.
Smart matching is available in Perl since 5.10.
Repeated op, static hash
Construct a hash that maps values to keys, and use that one as a natural hash to test key existence.
my %r = reverse %x;
if ( exists $r{2} ) { ... }
Repeated op, dynamic hash
Use a reverse lookup as above. You'll need to keep it up to date, which is left as an exercise to the reader/editor. (hint: value collisions are tricky)
my %reverse = reverse %x;
if( defined( $reverse{2} ) ) {
print "2 is a value in the hash!\n";
}
If you want to find out the keys for which the value is 2:
foreach my $key ( keys %x ) {
print "2 is the value for $key\n" if $x{$key} == 2;
}