Perl Cd Bookshelf [Electronic resources] نسخه متنی

اینجــــا یک کتابخانه دیجیتالی است

با بیش از 100000 منبع الکترونیکی رایگان به زبان فارسی ، عربی و انگلیسی

Perl Cd Bookshelf [Electronic resources] - نسخه متنی

| نمايش فراداده ، افزودن یک نقد و بررسی
افزودن به کتابخانه شخصی
ارسال به دوستان
جستجو در متن کتاب
بیشتر
تنظیمات قلم

فونت

اندازه قلم

+ - پیش فرض

حالت نمایش

روز نیمروز شب
جستجو در لغت نامه
بیشتر
لیست موضوعات
توضیحات
افزودن یادداشت جدید

5.8. Hashes with Multiple Values per Key


5.8.1. Problem


You want to store more than one value for
each key.

5.8.2. Solution


Store an array reference in $hash{$key}, then put
the values into the referenced array.

5.8.3. Discussion


You can store only 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
multivalued version of $ttys{$user}
= $tty. The first time through,
that hash value is undefined, so Perl automatically allocates a new
anonymous hash and stores its reference in that value so that the
push can succeed. This is called
autovivification, and is explained more in Chapter 11.

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 at least one value for this key?"
and "Does this value exist for this key?" Implementing the second
approach requires searching the array for the value. The
delete function and the first sense of
exists are interrelated: if we can guarantee that
no anonymous array is ever empty, we can use the built-in
exists. We ensure that no anonymous array is ever
empty by checking for that after deleting an element.

sub multihash_delete {
my ($hash, $key, $value) = @_;
my $i;
return unless ref( $hash->{$key} );
for ($i = 0; $i < @{ $hash->{$key} }; $i++) {
if ($hash->{$key}->[$i] eq $value) {
splice( @{$hash->{$key}}, $i, 1);
last;
}
}
delete $hash->{$key} unless @{$hash->{$key}};
}

An alternative approach to multivalued hashes is given in Chapter 13, implemented as tied normal hashes.

5.8.4. See Also


The splice, delete,
push, foreach, and
exists functions in
perlfunc(1) and Chapter 29
of Programming Perl; Recipe 11.1; we cover ties in Recipe 13.15

/ 875