How to iterate over hash keys using a reference in Perl?
Question
How to iterate over hash keys using a reference in Perl?
In Perl, hashes are very commonly used to store key-value pairs, and iterating over their keys is a fundamental task. When you work with a hash reference (a scalar that refers to a hash), the syntax for iteration slightly changes compared to iterating over a hash directly.
Iterating Over Hash Keys Using a Reference
Given a hash reference, you can dereference it to gain access to the underlying hash. There are several ways to do this:
keys %{$hash_ref}— The most common way to get the list of keys.each %{$hash_ref}— To iterate with key-value pairs.values %{$hash_ref}— If you want only the values.
Note the use of curly braces {} for dereferencing. The $hash_ref scalar contains a reference, so you must wrap it in %{} to treat it as a hash in scalar context.
Perl Concepts to Keep in Mind
- Sigils: The percent sign
%denotes a hash. When dealing with references, you use the scalar sigil$because the reference itself is a scalar. - Dereferencing: Accessing the actual data referred to by the reference. For hashes, this is done with
%{}. - Context: Functions like
keysreturn a list of keys in list context. When iterating, you typically assign or loop over this list. - TMTOWTDI ("There’s More Than One Way To Do It"): Perl offers various ways to iterate, such as looping with
foreachand usingwhile (each ...).
Example: Iterating Over Hash Keys From a Reference
use strict;
use warnings;
# Create a hash and get a reference to it
my %hash = (
apple => 'red',
banana => 'yellow',
grape => 'purple',
);
my $hash_ref = \%hash;
# Iterate over keys using the hash reference
print "Keys and their values:\n";
foreach my $key (keys %{$hash_ref}) {
print "$key => $hash_ref->{$key}\n";
}
# Another way: while each loop
print "\nUsing each loop:\n";
while (my ($k, $v) = each %{$hash_ref}) {
print "$k => $v\n";
}
This code outputs:
Keys and their values:
apple => red
banana => yellow
grape => purple
Using each loop:
apple => red
banana => yellow
grape => purple
Common Pitfalls
- Forgetting to dereference the hash reference with
%{}. Writingkeys $hash_refis incorrect and will cause a runtime error. - Mixing sigils improperly. Using
$hash_ref->{$key}to access the value is correct, but trying${hash_ref}{$key}won't work as expected. - Using
eachin a loop without resetting it viakeysor callingeachin list context first may cause unexpected iteration behavior.
Version Notes
- The syntax shown works in all modern Perl versions (5.x).
- In Perl 5.12 and later, you can use the
eachfunction on arrays as well, but for hashes, it works the same way.
By understanding these fundamental steps and syntax rules, you can confidently iterate over hash keys and values when working with references in Perl.
Verified Code
Executed in a sandbox to capture real output. • v5.34.1 • 5ms
Keys and their values:
apple => red
banana => yellow
grape => purple
Using each loop:
apple => red
banana => yellow
grape => purple
(empty)