perl:深度合并每个元素数组合并

时间:2016-02-27 05:00:05

标签: arrays perl merge

我试图合并两个哈希值Hash::Merge几乎完全符合我的需要,除了数组。我不需要连接数组,而是需要它来进行每元素合并。

例如:

use Hash::Merge qw (merge);

my %a = ( 'arr' => [ { 'a' => 'b' } ] );
my %b = ( 'arr' => [ { 'c' => 'd' } ] );

my %c = %{ merge( \%a, \%b) };

所需结果为('arr'=>[{'a'=>'b','c'=>'d'}]),实际结果为('arr'=>[{'a'=>'b'},{'c'=>'d'}])

可以使用specify_behavior完成此操作还是以其他方式完成?

2 个答案:

答案 0 :(得分:1)

我认为specify_behaviour用于指定如何处理冲突,或者指定要合并的不均匀结构。文档实际上并没有多说。但是尝试一下,通过定义的快捷方式,或者尝试自己设置它们。对于您的数据结构,您可以尝试

SCALAR => ARRAY => sub { [ %{$_0}, %{$_[0]} ] }
SCALAR => ARRAY => HASH => sub { [ $_[0], $_[0] ] }

如果你尝试过并且它没有工作,你可能在模块中发现了一个错误?根据你的表现,它只是没有深入"足够。这里没有模块。我扩大了你的样本结构。

use warnings;
use strict;

my %a = ( 
    'arr1' => [ { a => 'A', a1 => 'A1' } ],
    'arr2' => [ { aa => 'AA', aa1 => 'AA1' } ] 
);
my %b = ( 
    'arr1' => [ { b => 'B', b1 => 'B1' } ], 
    'arr2' => [ { bb => 'BB', bb1 => 'BB1' } ] 
);
# Copy top level, %a to our target %c
my %c;
@c{keys %a} = values %a;
# Iterate over hash keys, then through array
foreach my $key (sort keys %c) {
    my $arr_len = @{$c{$key}};
    foreach my $i (0..$arr_len-1) {
        my %hb = %{ ${$b{$key}}[$i] };
        # merge: add %b to %c
        @{ ${$c{$key}}[$i] }{keys %hb} = values %hb;
    }
}
# Print it out
foreach my $key (sort keys %c) {
    print "$key: ";
    my $arr_len = @{$c{$key}};
    foreach my $i (0..$arr_len-1) {
        my %hc = %{ ${$c{$key}}[$i] };
        print "$_ => $hc{$_}, " for sort keys %hc;
    }
    print "\n";
}

这将打印%c的内容(在此手动对齐)


   arr1: a  => A,  a1  => A1,  b  => B,  b1  => B1, 
   arr2: aa => AA, aa1 => AA1, bb => BB, bb1 => BB1,

代码不处理大小不等的数组/哈希值,但可以轻松添加检查。

答案 1 :(得分:0)

另一个解决方案(处理%a和%b中不均匀的哈希元素)。

my %c;

foreach my $key (keys %a, keys %b) {
    my $a_ref = $a{$key};
    my $b_ref = $b{$key};
    $c{$key} = { map %$_, @$a_ref, @$b_ref };
}

use Data::Dumper;
print Dumper \%c;