Is this the cleanest way to extract a subset of AoH in Perl?

Out of curiosity, is there any other way to extract a subset of my AoH structure? AoH is "rectangular" (i.e. it is guaranteed to have the same keys in all hashrefs).

Using a temporary var and a nested map seems too big for what is essentially a bizarre hash fragment:

 use strict; use warnings; use Data::Dump 'dump'; my $AoH = [ # There are many more keys in the real structure { a => "0.08", b => "0.10", c => "0.25" }, { a => "0.67", b => "0.85", c => "0.47" }, { a => "0.06", b => "0.57", c => "0.84" }, { a => "0.15", b => "0.67", c => "0.90" }, { a => "1.00", b => "0.36", c => "0.85" }, { a => "0.61", b => "0.19", c => "0.70" }, { a => "0.50", b => "0.27", c => "0.33" }, { a => "0.06", b => "0.69", c => "0.12" }, { a => "0.83", b => "0.27", c => "0.15" }, { a => "0.74", b => "0.25", c => "0.36" }, ]; # I just want the 'a and 'b's my @wantedKeys = qw/ ab /; # Could have multiple unwanted keys in reality my $a_b_only = [ map { my $row = $_; +{ map { $_ => $row->{$_} } @wantedKeys } } @$AoH ]; dump $a_b_only; # No 'c here 
+4
source share
4 answers

This does this with one map and an arbitrary list of keys:

 my @wantedKeys = qw/ab/; my $wanted = [ map { my %h; @h{@wantedKeys} = @{ $_ }{@wantedKeys}; \%h } @$AoH ]; 

(Help this post a bit)

+2
source

If you no longer need $ AoH, you can use the destructive method:

 delete $_->{c} for @$AoH; 
+2
source

You want to delete .

 my $foo = [ map { delete $_->{c}; $_ } @$AoH ]; 

If you want to keep the original data, you need to first dereference the hashes.

 my $foo = [ map { my %hash = %$_; delete $hash{c}; \%hash; } @$AoH ]; 
+1
source

This is my solution (let me introduce a nice Data :: Printer module):

 use Modern::Perl; use Data::Printer { colored => 1 }; my $AoH = [ { a => "0.08", b => "0.10", c => "0.25" }, { a => "0.67", b => "0.85", c => "0.47" }, { a => "0.06", b => "0.57", c => "0.84" }, { a => "0.15", b => "0.67", c => "0.90" }, { a => "1.00", b => "0.36", c => "0.85" }, { a => "0.61", b => "0.19", c => "0.70" }, { a => "0.50", b => "0.27", c => "0.33" }, { a => "0.06", b => "0.69", c => "0.12" }, { a => "0.83", b => "0.27", c => "0.15" }, { a => "0.74", b => "0.25", c => "0.36" }, ]; # I just want the 'a and 'b's, so I build a new hash with the keys I want my @ab = map { {a=>$_->{a}, b=>$_->{b}} } @$AoH; p @ab; # If you don't mind remove the "c" key in your original structure: # map { delete $_->{c} } @$AoH; # and $AoH is an array of hashes without the "c" key. 
+1
source

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


All Articles