Working with Perl’s references can sometimes be confusing. This document illustrates several ways to efficiently take a slice of a hash reference.
Here is a hash reference and an array of keys called @order
:
my $row = { foo => 'bar',
baz => 'blech',
one => 'uno',
tres => 'three',
cuatro => 'four or so' };
my @order = qw(one tres cuatro baz foo);
Here is one way to get a list of values in the order of @order
:
my @row = @$row{@order};
say "ROW: @row";
Prints:
ROW: uno three four or so blech bar
If you’re coming from Bourne-shell, you can use lots of curly braces:
@{$row}{@order}
You can also assign slices:
my $old = { foo => 1, bar => 2, baz => 3, blech => 4 };
my @fields = qw(foo bar baz);
my %new = ();
@new{@fields} = @{$old}{@fields};
If we want a slice of a hash of hashrefs:
$sum{foo}->{alpha} = 1;
$sum{foo}->{beta} = 2;
$sum{foo}->{gamma} = 3;
$sum{foo}->{mu} = 4;
What we need to remember is that the hashref has to be dereferenced into a hash first with curly braces. This is a hashref containing alpha, beta, etc:
$sum{foo}
Dereferenced to a hash looks like this:
%{$sum{$foo}}
And to take a slice, we use the @ sigil to tell Perl we want (context) an array of values, not key/value pairs:
my @all = @{$sum{foo}}{qw(alpha beta gamma mu)};
Last modified on 2012-05-08