Recipe 11.2 Making Hashes of Arrays

11.2.1 Problem

For each key in a hash, only one scalar value is allowed, but you'd like to use one key to store and retrieve multiple values. That is, you'd like the value to produce a list.

11.2.2 Solution

Use references to arrays as the hash values. Use push to append:

push(@{ $hash{"KEYNAME"} }, "new value");

Then, dereference the value as an array reference when printing out the hash:

foreach $string (keys %hash) {
    print "$string: @{$hash{$string}}\n";

11.2.3 Discussion

You can only store scalar values in a hash. References, however, are scalars. This solves the problem of storing multiple values for one key by making $hash{$key} a reference to an array containing the values for $key. Normal hash operations acting on individual scalar values (insertion, deletion, iteration, and testing for existence) are now written with array operations acting on lists of values (like push, splice, and foreach).

Here's how to give a key many values:

$hash{"a key"} = [ 3, 4, 5 ];       # anonymous array

Once you have a key with many values, here's how to use them:

@values = @{ $hash{"a key"} };

To append a new value to the array of values associated with a particular key, use push:

push @{ $hash{"a key"} }, $value;

One common application of such data structures is inverting a hash that may have several keys with the same associated value. When inverted, you end up with a hash that has many values for the same key. This is addressed in Recipe 5.9.

Be warned that this:

@residents = @{ $phone2name{$number} };

causes a runtime exception under use strict because you're dereferencing an undefined reference where autovivification won't occur. You must do this instead:

@residents = exists( $phone2name{$number} )
                       ? @{ $phone2name{$number} }
                       : ( );

11.2.4 See Also

The section on "Hashes of Arrays" in Chapter 9 of Programming Perl and in perldsc(1); the section on "Symbolic References" in Chapter 8 of Programming Perl; Recipe 5.9; Tie Example: Make a Hash That Always Appends in Recipe 13.15