Reputation: 1285
I love hash slices and use them frequently:
my %h;
@h{@keys}=@vals;
Works brilliantly! But 2 things have always vexed me.
First, is it possible to combine the 2 lines above into a single line of code? It would be nice to declare the hash and populate it all at once.
Second, is it possible to slice an existing anonymous hash... something like:
my $slice=$anonh->{@fields}
Upvotes: 10
Views: 1603
Reputation: 98398
For your first question, to do it in a single line of code:
@$_{@keys}=@vals for \my %h;
or
map @$_{@keys}=@vals, \my %h;
but I wouldn't do that; it's a confusing way to write it.
Either version declares the variable and immediately takes a reference to it and aliases $_
to the reference so that the hash reference can be used in a slice. This lets you declare the variable in the existing scope; @{ \my %h }{@keys} = @vals;
also "works", but has the unfortunate drawback of scoping %h
to that tiny block in the hash slice.
For your second question, as shown above, slices can be used on hash references; see http://perlmonks.org/?node=References+quick+reference for some easy to remember rules.
my @slice = @$anonh{@fields};
or maybe you meant:
my $slice = [ @$anonh{@fields} ];
but @slice/$slice there is a copy of the values. To get an array of aliases to the hash values, you can do:
my $slice = sub { \@_ }->( @$anonh{@fields} );
Upvotes: 8
Reputation: 386501
First question:
my %h = map { $keys[$_] => $vals[$_] } 0..$#keys;
or
use List::MoreUtils qw( mesh );
my %h = mesh @keys, @vals;
Second question:
If it's ...NAME...
for a hash, it's ...{ $href }...
for a hash ref, so
my @slice = @hash{@fields};
is
my @slice = @{ $anonh }{@fields};
The curlies are optional if the reference expression is a variable.
my @slice = @$anonh{@fields};
Upvotes: 9
Reputation: 118665
Hash slice syntax is
@ <hash-name-or-hash-ref> { LIST }
When you are slicing a hash reference, enclose it in curly braces so it doesn't get dereferenced as an array. This gives you:
my @values = @{$anonh}{@fields}
for a hash reference $anonh
.
Upvotes: 3