http://www.perlmonks.org?node_id=725312

thangappan has asked for the wisdom of the Perl Monks concerning the following question:

Normally in Perl,we can get values using keys as my $value = $hash{$keys} # It gives value of $key.Can any one explain how can I get keys using hash in Perl.Is there any way?

Replies are listed 'Best First'.
Re: get keys using values in hash.
by GrandFather (Saint) on Nov 22, 2008 at 09:10 UTC

    Do you mean "Given a value, how can I find the key?". If so the short answer is: "Probably you can't".

    The longer answer is that keys are unique for any given hash but values are not. For example a hash may contain the following key => value pairs:

    apple => red ball => red lemon => yellow lime => green grass => green

    The keys are unique, but the values (colours) are not. You can not ask for the single green object because there is more than one.

    If there were a one to one mapping (keys and values unique) then you could generate a second hash using the first hash's values as keys and the first hash's keys as values - you would then have a reverse lookup.

    If however you are asking "How do I get a list of the keys", the answer is trivial: keys.


    Perl reduces RSI - it saves typing
Re: get keys using values in hash.
by linuxer (Curate) on Nov 22, 2008 at 11:45 UTC

    You could try something like this:

    #!/usr/bin/perl -l # vi:ts=4 sw=4 et: use strict; use warnings; my %hash = ( apple => 'red', ball => 'red', lemon => 'yellow', lime => 'green', grass => 'green', ); my $search = 'green'; # get all keys, which have $search as value my @keys = grep { $hash{$_} eq $search } keys %hash; print "@keys";
Re: get keys using values in hash.
by ccn (Vicar) on Nov 22, 2008 at 09:10 UTC
    You can do it somehow. If %rev = reverse %hash; than $rev{$value} gives a key. But it works not for all cases.

    Note that keys are unique but values can be not unique. So if different keys have the same value how do you want to reverse them?

Hash Inversion
by LanX (Saint) on Nov 22, 2008 at 20:22 UTC
    you mean plural? all keys per value?
    use strict; use warnings; use Data::Dumper; my %hash = ( apple => 'red', ball => 'red', lemon => 'yellow', lime => 'green', grass => 'green', ); my %rev; #= version 1 %rev=(); for my $value (values %hash) { $rev{$value}=[ grep { $hash{$_} eq $value } keys %hash ]; } print Dumper \%rev; #= version 2 %rev=(); while (my ($k,$v) = each %hash) { push @{ $rev{$v} }, $k ; } print Dumper \%rev; #= version 2b # not really shorter under strict ... %rev=(); my ($k,$v); push @{ $rev{$v} } , $k while ( ($k,$v) = each %hash); print Dumper \%rev; #= version 2c # hmm maybe finally a good application of builtin pkgvars $a and $b ; +) # VIVA LA AUTOVIVICACION! 8 ) %rev=(); push @{ $rev{$b} } , $a while ( ($a,$b) = each %hash); print Dumper \%rev; __END__ #OUTPUT $VAR1 = { 'green' => [ 'grass', 'lime' ], 'red' => [ 'apple', 'ball' ], 'yellow' => [ 'lemon' ] }; ...
    I'm sure there must be a modul doing this, but I couldn't find it ... at least in core-moduls ...

    Cheers Rolf