next up previous contents
Next: Basic I/O Up: Hashes Previous: Hashes and Lists   Contents

Functions for Working with Hashes

One of the most common tasks when working with hashes is to iterate over all the values stored in the hash. Unlike a regular array, where you can directly use a foreach loop, or iterate over the (consecutive integer) indices, with a hash you must either use the each function inside a while loop, or first use the keys function to access an array containing the values of all the keys which have been defined for the hash. Since these functions operate on the entire hash, you need to use the percent sign (%) in the hash's name when you call them.

The each function, used in the clause of a while loop, is the most efficient way to iterate over the elements in the array. It returns a list consisting a key/value pair from the hash passed to it. Each time the each function is called, it returns another key/value pair, in no discernible order. Most perl programmers will assign the values to a literal list, and then use the elements of that list in the body of the while loop. So to print the names and instruments of all the musicians in the %instrument hash, you could use code like the following:

     while(($k,$v) =  each(%instrument)){
         print "$k plays $v\n";
     }
All calls to each for a given hash will iterate over the same list. The next call to each after the last key/value pair is accessed will return a null array, which explains why the while loop in the above example stops when it has accessed all the key/value pairs in the hash. After the function returns this null array, the next call to each starts the process over again. Although the rules for each's behavior are the same regardless of whether it's called in the clause of a while loop or in some other context, each is usually most useful when used as in the example above. To force the each function to start over before it has iterated through all the values, you can call the keys or values functions which are described below, since all three function share the same iterator.

An alternative to using the each function is to use the keys function to extract the keys of a hash into an array, and then to process that array in order to access all the elements of a hash. Just as the each function returns key/value pairs in a seemingly random order, the order of the elements in the array returned by the keys function is not predictable -- it's determined by the algorithm that perl uses to quickly find the keys you ask for. For this reason, it's common to use the sort function (Section [*]) on the array returned by keys.

Suppose we have a hash name %phone that contains the phone numbers for various people and the keys to the hash are the names of those people. In order to print a list of the people and their phone numbers using the keys function, we could use a program like this one:

     @folks = keys(%phone);
     foreach $f (@folks){
         print "$f $phone{$f}\n";
     }

The counterpart to keys is the function values, which returns an array containing just the values of a hash. These values are returned in the same order as the keys function returns the keys.

Finally, the delete function solves an interesting problem: How can we remove a key/value pair from a hash? Note that it's not enough to just set the value for a particular key to an undefined value -- that would still leave the key in the hash, and only change it's value. So when you want to completely remove a key/value pair from a hash, you should use the delete function. (Recall from Section 2.3 that the undef function can be used to remove an entire hash, just as it can for any perl variable.) As a simple example, we could eliminate the entry in the %instrument hash whose key is ``monk'' with the following statement:

     delete $instrument{monk};
If you attempt to delete a non-existent key/value pair, perl will simply ignore the request without printing a warning or error.
next up previous contents
Next: Basic I/O Up: Hashes Previous: Hashes and Lists   Contents
Phil Spector 2002-10-18