perl:与每个元素阵列合并深度合并
问题描述:
我想合并两个哈希,并且Hash::Merge
几乎正是我所需要的,除了数组。我不需要连接数组,而是需要它执行每个元素的合并。perl:与每个元素阵列合并深度合并
例如:
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
完成或者是有一些其他的方式?
答
我认为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,
代码不处理的阵列/不相等的大小,但检查的哈希可以容易地添加。
答
另一种解决方案(处理%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;
我不认为有''specify_behavior'方法,但我不熟悉这个模块。我相信它通过将2个散列引用数组合并成1个散列引用数组来执行期望的行为。我认为要深度合并,你必须编写更多的代码。但是,我真的不知道这个模块。注意:你需要一个带有1个元素的数组(一个散列引用),你可能会更好地使用带有深元素的散列引用。只是一个观察。 –