Hashes with Multiple Values Per Key
Problem
You want to store more than one value for each key.
Solution
Store an array reference in $hash{$key}, and put
the values into that array.
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 values for $key. The normal hash
operations—insertion, deletion, iteration, and testing for
existence—can now be written in terms of array operations
like push, splice, and
foreach.
This code shows simple insertion into the hash. It processes the
output of who(1) on Unix machines and outputs a
terse listing of users and the ttys they’re logged in on:
%ttys = ();
open(WHO, "who|") or die "can't open who: $!";
while (<WHO>) {
($user, $tty) = split;
push( @{$ttys{$user}}, $tty );
}
foreach $user (sort keys %ttys) {
print "$user: @{$ttys{$user}}\n";
}The heart of the code is the push line, the
multihash version of $ttys{$user}
=
$tty. We interpolate all the
tty names in the print line with
@{$ttys{$user}}. We’d loop over the
anonymous array if, for instance, we wanted to print the owner of
each tty:
foreach $user (sort keys %ttys) {
print "$user: ", scalar( @{$ttys{$user}} ), " ttys.\n";
foreach $tty (sort @{$ttys{$user}}) {
@stat = stat("/dev/$tty");
$user = @stat ? ( getpwuid($stat[4]) )[0] : "(not available)";
print "\t$tty (owned by $user)\n";
}
}
The exists function can have two meanings: “Is there ...
Become an O’Reilly member and get unlimited access to this title plus top books and audiobooks from O’Reilly and nearly 200 top publishers, thousands of courses curated by job role, 150+ live events each month,
and much more.
Read now
Unlock full access