Cleaner way to store to replace a scalar hash value with an array ref?
I am building a hash where the keys, associated with scalars, are not necessarily unique. The desired behavior to be that if the key is unique, the value is the scalar. If the key is not unique, I want the value to be an array reference of the scalars associated witht the key. Since the hash is built up iteratively, I don't know if the key is unique ahead of 开发者_Python百科time. Right now, I am doing something like this:
if(!defined($hash{$key})){
$hash{$key} = $val;
}
elseif(ref($hash{$key}) ne 'ARRAY'){
my @a;
push(@a, $hash{$key});
push(@, $val);
$hash{$key} = \@a;
}
else{
push(@{$hash{$key}}, $val);
}
Is there a simpler way to do this?
rjh is right on the money.
I have written way too much code that does exactly what you describe--the hash value is an array ref unless it isn't. Reams and reams of conditional type checking. Then one day it hit me, "Why am I writing all this crap? Just use an array ref everywhere, dummy" I said to myself. Since that day bluebirds fly down from the trees to sing to me whenever I walk in the park.
push @{$hash{$key}}, $val;
That's all you have to do. If the key does not exist, the array is autovivified.
If you don't like autoviv, and want to be explicit do:
$hash{$key} = [] unless exists $hash{$key};
push @{$hash{$key}}, $val;
Even this 'verbose' approach is much shorter.
if(!defined($hash{$key})){
$hash{$key} = $val;
}
elsif (ref($hash{$key}) ne 'ARRAY') {
$hash{$key} = [ $hash{$key}, $val ];
}
else{
push(@{$hash{$key}}, $val);
}
精彩评论