Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to test if a value exist in a hash?

Tags:

perl

Let's say I have this

#!/usr/bin/perl

%x = ('a' => 1, 'b' => 2, 'c' => 3);

and I would like to know if the value 2 is a hash value in %x.

How is that done?

like image 312
Sandra Schlichting Avatar asked Jan 14 '11 23:01

Sandra Schlichting


People also ask

How do you check if a value exists in a hash Perl?

The exists() function in Perl is used to check whether an element in an given array or hash exists or not. This function returns 1 if the desired element is present in the given array or hash else returns 0.

Whats the most efficient way of knowing whether a key exist in the hash table?

containsKey() method is used to check whether a particular key is present in the Hashtable or not. It takes the key element as a parameter and returns True if that element is present in the table.

How do I check if a Perl hash is empty?

From perldoc perldata: If you evaluate a hash in scalar context, it returns false if the hash is empty. If there are any key/value pairs, it returns true; more precisely, the value returned is a string consisting of the number of used buckets and the number of allocated buckets, separated by a slash.


2 Answers

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 spelled grep {$_==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. Use defined 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)

like image 59
JB. Avatar answered Oct 21 '22 12:10

JB.


Where $count would be the result:

my $count = grep { $_ == 2 } values %x;

This will not only show you if it's a value in the hash, but how many times it occurs as a value. Alternatively you can do it like this as well:

my $count = grep {/2/} values %x;
like image 45
phfeenikz Avatar answered Oct 21 '22 12:10

phfeenikz