Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Perl: Hash ref accessing array of keys

Tags:

hash

perl

I have a question that seems basic, but I can't figure out. Say that I have a hash reference in Perl. I want to get an array of values through an array of keys.

Here's how it'd work with a hash, not a hash reference:

my %testHash = ( "a" => 1, "b" => 2, "c" => 3 );
my @testKeys = ("a", "b", "c");

my @testValues = @testHash{@testKeys};

Now suppose I have a hash reference,

my $hashRef = {"a" => 1, "b" => 2, "c" => 3};

I've tried the following two ways:

my @values = @{$hashRef->{@testKeys}};
my @values = $hashRef->{@testKeys};

But neither is correct. Is there a correct way, or do I just have to dereference the hash ref every time I want to do this?

like image 991
Tianxiang Xiong Avatar asked Nov 15 '11 04:11

Tianxiang Xiong


1 Answers

You're close:

my @values = @$hashref{@testKeys};     ## (1)

or

my @values = @{$hashref}{@testKeys};   ## (2)

For more examples, see "Slices" in the perllol documentation.

"Using References" in the perlref documentation gives the general rules.

1. Anywhere you'd put an identifier (or chain of identifiers) as part of a variable or subroutine name, you can replace the identifier with a simple scalar variable containing a reference of the correct type.

This explains why (1) works: you replaced the identifier testHash with the simple scalar $hashRef.

2. Anywhere you'd put an identifier (or chain of identifiers) as part of a variable or subroutine name, you can replace the identifier with a BLOCK returning a reference of the correct type.

Snippet (2) above is nearly the same but has a little bulkier syntax. In place of the identifier testHash, you write a block returning a reference to a hash, i.e., {$hashRef}.

The braces here enclose a bona fide block, so you can compute and return a reference, as in

push @{ $cond ? \@a1 : \@a2 }, "some value";
like image 138
Greg Bacon Avatar answered Oct 12 '22 14:10

Greg Bacon