perl - Hash::Merge 在散列中复制相同的列表而不是将它们放一次
perl - Hash::Merge duplicates same list within hashes instead of putting them once
我正在尝试合并两个包含列表的散列。
问题是那些列表完全相同,但是因为它们是列表,所以合并会在内部复制它们的值。
有什么办法可以删除重复项吗?
#!usr/bin/perl
use strict;
use warnings;
use Hash::Merge;
use Data::Dumper;
$Data::Dumper::Sortkeys = 1;
my $hash1 = {
'Instance' => [ 1,2 ]
};
my $hash2 = {
'Instance' => [ 1,2 ]
};
my $merger = Hash::Merge->new('LEFT_PRECEDENT');
my $hash3 = $merger->merge($hash2, $hash1);
print Dumper($hash3);
输出:
$VAR1 = {
'Instance' => [
1,
2,
1,
2
]
};
我想要的是:
$VAR1 = {
'Instance' => [
1,
2
]
};
编辑后:
我发了一个持续 question.
当您想使用 Hash::Merge
做一些更高级的事情时,答案通常是“实现您自己的自定义行为”。
在这种情况下,你可以这样做:
my $merger = Hash::Merge->new('LEFT_PRECEDENT');
my $behavior = $merger->get_behavior_spec($merger->get_behavior);
$behavior->{ARRAY}{ARRAY} = sub {
my ($left, $right) = @_;
my %seen = map { $_ => 1 } @$left;
return [ @$left, grep { ! $seen{$_} } @$right ];
};
my $hash3 = $merger->merge($hash2, $hash1);
行 my %seen = map { $_ => 1 } @$left;
使用 $left
数组的值填充散列 %seen
,并且 grep { ! $seen{$_} } @$right
通过仅保留 $right
过滤 $right
数组不在 %seen
.
中的值
请注意,此方法不会删除所有重复项:如果 $left
或 $right
包含重复元素(例如,如果 $left = [1, 1, 2]
),那么这些重复项将保留。如果您想删除所有重复项,请改用此版本:
use List::MoreUtils qw(uniq);
$behavior->{ARRAY}{ARRAY} = sub {
my ($left, $right) = @_;
return [ uniq @$left, @$right ];
};
如果您出于任何原因不想依赖 List::MoreUtils
for the uniq
function, you can easily implement your own: How do I remove duplicate items from an array in Perl?。
我正在尝试合并两个包含列表的散列。 问题是那些列表完全相同,但是因为它们是列表,所以合并会在内部复制它们的值。
有什么办法可以删除重复项吗?
#!usr/bin/perl
use strict;
use warnings;
use Hash::Merge;
use Data::Dumper;
$Data::Dumper::Sortkeys = 1;
my $hash1 = {
'Instance' => [ 1,2 ]
};
my $hash2 = {
'Instance' => [ 1,2 ]
};
my $merger = Hash::Merge->new('LEFT_PRECEDENT');
my $hash3 = $merger->merge($hash2, $hash1);
print Dumper($hash3);
输出:
$VAR1 = {
'Instance' => [
1,
2,
1,
2
]
};
我想要的是:
$VAR1 = {
'Instance' => [
1,
2
]
};
编辑后: 我发了一个持续 question.
当您想使用 Hash::Merge
做一些更高级的事情时,答案通常是“实现您自己的自定义行为”。
在这种情况下,你可以这样做:
my $merger = Hash::Merge->new('LEFT_PRECEDENT');
my $behavior = $merger->get_behavior_spec($merger->get_behavior);
$behavior->{ARRAY}{ARRAY} = sub {
my ($left, $right) = @_;
my %seen = map { $_ => 1 } @$left;
return [ @$left, grep { ! $seen{$_} } @$right ];
};
my $hash3 = $merger->merge($hash2, $hash1);
行 my %seen = map { $_ => 1 } @$left;
使用 $left
数组的值填充散列 %seen
,并且 grep { ! $seen{$_} } @$right
通过仅保留 $right
过滤 $right
数组不在 %seen
.
请注意,此方法不会删除所有重复项:如果 $left
或 $right
包含重复元素(例如,如果 $left = [1, 1, 2]
),那么这些重复项将保留。如果您想删除所有重复项,请改用此版本:
use List::MoreUtils qw(uniq);
$behavior->{ARRAY}{ARRAY} = sub {
my ($left, $right) = @_;
return [ uniq @$left, @$right ];
};
如果您出于任何原因不想依赖 List::MoreUtils
for the uniq
function, you can easily implement your own: How do I remove duplicate items from an array in Perl?。