Perl使用Hash::Merge合并哈希内相同列表时出现重复值如何解决
Hash::Merge 合并哈希时避免数组元素重复的解决方法
问题原因
Hash::Merge 默认的数组合并规则为直接拼接两个输入数组,因此当两个哈希的同键对应数组存在重叠元素时就会出现重复内容。
解决方案
方案1:自定义Hash::Merge合并规则
通过specify_behavior方法重写数组与数组的合并逻辑,合并时直接对结果去重,后续调用合并方法时自动生效:
#!/usr/bin/perl use strict; use warnings; use Hash::Merge; use Data::Dumper; use List::Util qw(uniq); $Data::Dumper::Sortkeys = 1; my $hash1 = { 'Instance' => [ 1,2 ] }; my $hash2 = { 'Instance' => [ 1,2 ] }; # 自定义去重合并规则 Hash::Merge::specify_behavior( { 'SCALAR' => { 'SCALAR' => sub { $_[0] }, 'ARRAY' => sub { [ $_[0], @{$_[1]} ] }, 'HASH' => sub { $_[0] }, }, 'ARRAY' => { 'SCALAR' => sub { [ @{$_[0]}, $_[1] ] }, # 重写数组合并逻辑,返回去重后的数组 'ARRAY' => sub { [ uniq @{$_[0]}, @{$_[1]} ] }, 'HASH' => sub { $_[0] }, }, 'HASH' => { 'SCALAR' => sub { $_[0] }, 'ARRAY' => sub { $_[0] }, 'HASH' => sub { Hash::Merge::_merge_hashes( $_[0], $_[1] ) }, }, }, # 自定义规则命名 'UNIQUE_ARRAY_MERGE' ); my $merger = Hash::Merge->new('UNIQUE_ARRAY_MERGE'); my $hash3 = $merger->merge($hash2, $hash1); print Dumper($hash3);
运行上述代码将直接输出你期望的无重复结果。
方案2:合并完成后手动去重
如果不需要修改全局合并逻辑,可在得到合并结果后,遍历哈希对所有数组类型的值做去重处理:
#!/usr/bin/perl use strict; use warnings; use Hash::Merge; use Data::Dumper; use List::Util qw(uniq); $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); # 遍历哈希对数组去重 while (my ($key, $value) = each %$hash3) { $hash3->{$key} = [ uniq @$value ] if ref $value eq 'ARRAY'; } print Dumper($hash3);
注:Perl 5.26及以上版本自带的
List::Util::uniq会保留元素首次出现的顺序,符合常规使用需求。
内容的提问来源于stack exchange,提问作者urie
相关产品推荐
相关产品推荐

