Say I have a hash that I can index as:
$hash{$document}{$word}
From what I read online (although I could not find this on perlreftut, perldsc or perllol), I can slice a hash using a list if I use the @
prefix on my hash to indicate that I want the hash to return a list. However, if I try to slice my hash using a list @list
:
@%hash{$document}{@list}
I get several "Scalar values ... better written"
errors.
How can I slash a nested hash in Perl?
The sigill for your hash must be @
, like so:
@{$hash{$document}}{@list}
Assuming @list
contains valid keys for %hash
it will return the corresponding values, or undef
if the key does not exist.
This is based on the general rule of a hash slice:
%foo = ( a => 1, b => 2, c => 3 );
print @foo{'a','b'}; # prints 12
%bar = ( foo => \%foo ); # foo is now a reference in %bar
print @{ $bar{foo} }{'a','b'}; # prints 12, same data as before
First, when you expect to get a list from a hash slice, use @
sigil first. %
is pointless here.
Second, you should understand that $hash{$document}
value is not a hash or array. It's a reference - to a hash OR to an array.
With all this said, you might use something like this:
@{ $hash{$document} }{ @list };
... so you dereference value of $hash{$document}
, then use a hash slice over it. For example:
my %hash = (
'one' => {
'first' => 1,
'second' => 2,
},
'two' => {
'third' => 3,
'fourth' => 4,
}
);
my $key = 'one';
my @list = ('first', 'second');
print $_, "\n" for @{ $hash{$key} }{@list};
# ...gives 1\n2\n