You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何合并Perl中包含哈希的数组并去除重复哈希元素

你遇到的问题本质是List::MoreUtils的uniq函数基于元素字符串化结果去重,而数组中存储的是哈希引用,字符串化后得到的是内存地址(如HASH(0xabc123)),两个内容完全一致的哈希引用只要是不同的实例,内存地址就不同,因此无法被识别为重复项。

方案1:合并后轻量去重(适合固定结构场景)

如果你当前的哈希结构固定只有sport和country两个判断重复的字段,可以直接拼接两个字段值作为去重标识,无需引入额外模块:

use strict;
use Hash::Merge qw/merge/;
use Data::Dumper;

my $h1 = { name1    => [ {
                           sport  => "tennis",
                           country => "us",
                          },
                          {
                           sport => "soccer",
                           country => "brazil",
                          },
                          {
                           sport  => "cricket",
                           country => "india"
                          },
                        ]
        };

my $h2 = { name1 => [   {
                           sport => "soccer",
                           country => "brazil",
                          },

                        {
                           sport  => "boxing",
                           country => "china"
                         }
                          ],

        };

# 执行默认合并
my $merged = merge($h1, $h2);

# 对合并后的数组去重
my %seen;
$merged->{name1} = [
    grep { !$seen{$_->{sport} . '|' . $_->{country}}++ }
    @{$merged->{name1}}
];

print Dumper($merged);

方案2:自定义Hash::Merge合并规则(一次配置全局生效)

如果希望合并时自动完成去重,不需要后续单独处理,可以自定义Hash::Merge的数组合并行为:

use strict;
use Hash::Merge qw/merge/;
use Data::Dumper;

# 注册自定义合并规则
Hash::Merge::specify_behavior(
    {
        'SCALAR' => {
            'SCALAR' => sub { $_[1] },
            'ARRAY'  => sub { [ $_[0], @{$_[1]} ] },
            'HASH'   => sub { $_[1] },
        },
        'ARRAY' => {
            'SCALAR' => sub { [ @{$_[0]}, $_[1] ] },
            'ARRAY'  => sub {
                my %seen;
                my @combined = (@{$_[0]}, @{$_[1]});
                # 可根据实际字段调整去重标识拼接规则
                [ grep { !$seen{$_->{sport} . '|' . $_->{country}}++ } @combined ];
            },
            'HASH'   => sub { $_[1] },
        },
        'HASH' => {
            'SCALAR' => sub { $_[1] },
            'ARRAY'  => sub { $_[1] },
            'HASH'   => sub { Hash::Merge::_merge_hashes( $_[0], $_[1] ) },
        },
    },
    'ARRAY_WITH_UNIQUE_HASH'
);
# 启用自定义规则
Hash::Merge::set_behavior('ARRAY_WITH_UNIQUE_HASH');

my $h1 = { name1    => [ {
                           sport  => "tennis",
                           country => "us",
                          },
                          {
                           sport => "soccer",
                           country => "brazil",
                          },
                          {
                           sport  => "cricket",
                           country => "india"
                          },
                        ]
        };

my $h2 = { name1 => [   {
                           sport => "soccer",
                           country => "brazil",
                          },

                        {
                           sport  => "boxing",
                           country => "china"
                         }
                          ],

        };

# 直接合并即可自动去重
my $merged = merge($h1, $h2);
print Dumper($merged);

两种方案最终输出的结果都会去掉重复的{sport => "soccer", country => "brazil"}项:

$VAR1 = {
          'name1' => [
                       {
                         'country' => 'us',
                         'sport' => 'tennis'
                       },
                       {
                         'country' => 'brazil',
                         'sport' => 'soccer'
                       },
                       {
                         'sport' => 'cricket',
                         'country' => 'india'
                       },
                       {
                         'country' => 'china',
                         'sport' => 'boxing'
                       }
                     ]
        };

如果你的哈希结构不固定,判断重复需要匹配所有键值,可以用JSON::PP或者Storable模块把哈希序列化为字符串作为去重标识,替换掉上面的字段拼接逻辑即可。

内容的提问来源于stack exchange,提问作者kathy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 09:36:07