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?