Recipe 5.9 Inverting a Hash

5.9.1 Problem

Hashes
map keys to values. You have a hash and a value whose corresponding
key you want to find.

5.9.2 Solution

Use reverse to create an inverted hash whose
values are the original hash's keys and vice
versa.

# %LOOKUP maps keys to values
%REVERSE = reverse %LOOKUP;

5.9.3 Discussion

This technique uses the list equivalence of hashes mentioned in the
introduction. In list context, reverse treats
%LOOKUP as a list and reverses the order of its
elements. The significant property of a hash treated as a list is
that the list elements come in associated pairs: the first element is
the key; the second, the value. When you reverse
such a list, the first element is now the value, and the second the
key. Treating this list as a hash results in a
hash whose values are the keys of the original hash and vice versa.

If two keys in the original hash have the same value (as
"Lemon" and "Banana" do in the
color example), then the inverted hash will only have one (which is
dependent on the hashing order, and you shouldn't try to predict it).
This is because hashes have, by Perl definition, unique keys.

If you want to invert a hash with non-unique values, you must use the
techniques shown in Recipe 5.8. That is,
build up a hash whose values are a list of keys in the original hash:

This also lets us change the foodfind program to
handle colors represented by more than one food. For instance,
foodfindyellow reports bananas
and lemons.

If any values in the original hash were references instead of strings
or numbers, the inverted hash poses a problem because references
don't work well as hash keysunless you use the Tie::RefHash
module described in Recipe 5.13.

5.9.4 See Also

The reverse function in
perlfunc(1) and in Chapter 29 of
Programming Perl; Recipe 13.15