5.3. Hash FunctionsNaturally, there are some useful functions that can work on an entire hash at once. 5.3.1. The keys and values FunctionsThe keys function yields a list of all the current keys in a hash, while the values function gives the corresponding values. If there are no elements to the hash, then either function returns an empty list: my %hash = ("a" => 1, "b" => 2, "c" => 3); my @k = keys %hash; my @v = values %hash; So, @k will contain "a", "b", and "c", and @v will contain 1, 2, and 3 -- in some order. Remember, Perl doesn't maintain the order of elements in a hash. But, whatever order the keys are in, the values will be in the corresponding order: If "b" is last in the keys, 2 will be last in the values; if "c" is the first key, 3 will be the first value. That's true as long as you don't modify the hash between the request for the keys and the one for the values. If you add elements to the hash, Perl reserves the right to rearrange it as needed, to keep the access quick.[131]
In a scalar context, these functions give the number of elements (key-value pairs) in the hash. They do this quite efficiently, without having to visit each element of the hash: my $count = keys %hash; # gets 3, meaning three key-value pairs Once in a long while, you'll see that someone has used a hash as a Boolean (true/false) expression, something like this: if (%hash) { print "That was a true value!\n"; } That will be true if (and only if) the hash has at least one key-value pair.[132] So, it's just saying, "if the hash is not empty...". But this is a pretty rare construct, as such things go.
5.3.2. The each FunctionIf you wish to iterate over (that is, examine every element of) an entire hash, one of the usual ways is to use the each function, which returns a key-value pair as a two-element list.[133] On each evaluation of this function for the same array, the next successive key-value pair is returned, until all the elements have been accessed. When there are no more pairs, each returns an empty list.
In practice, the only way to use each is in a while loop, something like this: while ( ($key, $value) = each %hash ) { print "$key => $value\n"; } There's a lot going on here. First, each %hash returns a key-value pair from the hash, as a two-element list; let's say that the key is "c" and the value is 3, so the list is ("c", 3). That list is assigned to the list ($key, $value), so $key becomes "c", and $value becomes 3. But that list assignment is happening in the conditional expression of the while loop, which is a scalar context. (Specifically, it's a Boolean context, looking for a true/false value; and a Boolean context is a particular kind of scalar context.) The value of a list assignment in a scalar context is the number of elements in the source list -- 2, in this case. Since 2 is a true value, we enter the body of the loop and print the message c => 3. The next time through the loop, each %hash gives a new key-value pair; let's say it's ("a", 1) this time. (It knows to return a different pair than previously because it keeps track of where it is; in technical jargon, there's an iterator stored in with each hash.[134]) Those two items are stored into ($key, $value). Since the number of elements in the source list was again 2, a true value, the while condition is true, and the loop body runs again, telling us a => 1.
We go one more time through the loop, and by now we know what to expect, so it's no surprise to see b => 2 appear in the output. But we knew it couldn't go on forever. Now, when Perl evaluates each %hash, there are no more key-value pairs available. So, each has to return an empty list.[135] The empty list is assigned to ($key, $value), so $key gets undef, and $value also gets undef.
But that hardly matters, because the whole thing is being evaluated in the conditional expression of the while loop. The value of a list assignment in a scalar context is the number of elements in the source list -- in this case, that's 0. Since 0 is a false value, the while loop is done, and execution continues with the rest of the program. Of course, each returns the key-value pairs in a jumbled order. (It's the same order as keys and values would give, incidentally; the "natural" order of the hash.) If you need to go through the hash in order, simply sort the keys, perhaps something like this: foreach $key (sort keys %hash) { $value = $hash{$key}; print "$key => $value\n"; # Or, we could have avoided the extra $value variable: # print "$key => $hash{$key}\n"; } We'll see more about sorting hashes in Chapter 15, "Strings and Sorting". Copyright © 2002 O'Reilly & Associates. All rights reserved. |
|