Это самый чистый способ извлечь подмножество AoH в Perl? - PullRequest
4 голосов
/ 13 ноября 2011

Из любопытства, есть ли другой способ извлечь подмножество моей структуры AoH?AoH является «прямоугольным» (то есть гарантированно имеет одинаковые ключи для всех хеш-ссылок).

Использование временного var и вложенных map s кажется слишком большим для того, что по сути является причудливым фрагментом хеш-кода:

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's and 'b's

my @wantedKeys = qw/ a b /;  # Could have multiple unwanted keys in reality

my $a_b_only = [
                  map { my $row = $_;
                        +{
                           map { $_ => $row->{$_} } @wantedKeys
                         }
                  }
                  @$AoH
               ];

dump $a_b_only; # No 'c's here

Ответы [ 4 ]

2 голосов
/ 14 ноября 2011

Это делается с одним map и произвольным списком ключей:

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

(С небольшой помощью этот пост )

2 голосов
/ 13 ноября 2011

Если вам больше не нужен $ AoH, вы можете использовать деструктивный способ:

delete $_->{c} for @$AoH;
1 голос
/ 13 ноября 2011

Это мое решение (позвольте мне представить хороший модуль Data :: Printer):

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's 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 голос
/ 13 ноября 2011

Вы хотите delete.

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

Если вы хотите сохранить исходные данные, то вам нужно сначала разыменовать хеши.

my $foo = [ map { my %hash = %$_; delete $hash{c}; \%hash; } @$AoH ];
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...