Perl Hash::Merge合并哈希内相同列表时重复插入,如何去重?
问题根源
你当前的去重逻辑失效,核心原因是数组内的元素是哈希引用:Perl 中将引用作为哈希的键时,会自动把引用的内存地址转为字符串(你输出里的HASH(0xdd1af8)就是转换后的结果)。两个内容完全相同、但内存地址不同的哈希引用,转换后的字符串并不一致,所以%seen的判断逻辑无法识别出重复内容。
解决方案
我们可以对嵌套结构做内容序列化,用序列化后的结果作为去重的判断依据:内容完全相同的结构序列化后得到的结果一致,就能实现按内容去重。这里推荐用Storable模块的freeze函数,它支持任意层级嵌套结构的深度序列化。
修改后的完整代码
#!usr/bin/perl use strict; use warnings; use Hash::Merge; use Data::Dumper; # 新增引入序列化函数 use Storable qw(freeze); $Data::Dumper::Sortkeys = 1; my $hash1 = { 'EndHeaderExists' => [ { 'i' => 1 } ] }; my $hash2 = { 'EndHeaderExists' => [ { 'i' => 1 } ] }; 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 { freeze($_) => 1 } @$left; return [ @$left, grep { ! $seen{freeze($_)} } @$right ]; }; my $hash3 = $merger->merge($hash2, $hash1); print Dumper($hash3);
运行输出(符合预期)
$VAR1 = { 'EndHeaderExists' => [ { 'i' => 1 } ] };
注意事项
如果你的嵌套结构中包含对象、函数引用等特殊类型,需要确认序列化逻辑适配;普通的哈希、数组嵌套场景,该方案可以稳定生效。
内容的提问来源于stack exchange,提问作者urie
相关产品推荐
相关产品推荐

