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 ...
Get Perl Cookbook now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.