Pure storage method to replace scalar hash value with ref array?

I create a hash where the keys associated with scalars are not necessarily unique. The desired behavior is that if the key is unique, the value is a scalar. If the key is not unique, I want this value to be a reference to an array of scalars associated with the key. Since the hash is iterated, I donโ€™t know if the key is unique ahead of time. Right now, I'm 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 an easier way to do this?

+4
source share
2 answers

rjh right for the money.

I have written too much code that does exactly what you are describing - the hash value is a ref array if that is not the case. Covers and pins of conditional type. Then one day he hit me: โ€œWhy am I writing all this shit? Just use the ref array everywhere, dummy,โ€ I told myself. From that day, blue birds fly away from the trees to sing to me whenever I walk in the park.

 push @{$hash{$key}}, $val; 

That is all you need. If the key does not exist, the array is autogenerated.

If you do not like autoviv and want to be explicit:

 $hash{$key} = [] unless exists $hash{$key}; push @{$hash{$key}}, $val; 

Even this โ€œdetailedโ€ approach is much shorter.

+5
source
 if(!defined($hash{$key})){ $hash{$key} = $val; } elsif (ref($hash{$key}) ne 'ARRAY') { $hash{$key} = [ $hash{$key}, $val ]; } else{ push(@{$hash{$key}}, $val); } 
+1
source

Source: https://habr.com/ru/post/1306369/


All Articles