2012-09-24 82 views
5

这是我的散列的转储:%HASH1哈希合并/级联

$VAR1 = { 
    abc => { 
     123 => [ 
      'xx', 
      'yy', 
      'zy' 
     ], 
     456 => [ 
      'ab', 
      'cd', 
      'ef' 
     ] 
    } 
}; 

,第二个:%HASH2

$VAR2 = { 
    def => { 
     659 => [ 
      'wx', 
      'yg', 
      'kl' 
     ], 
     456 => [ 
      'as', 
      'sd', 
      'df' 
     ] 
    }, 
    abc => { 
     987 => [ 
      'lk', 
      'dm', 
      'sd' 
     ] 
    } 
}; 

现在,我想在一个新的哈希这两个散列合并,但是如果一个键被重复(这里'abc'),这些值应该被追加,而不是被替换,所以键应该保持唯一,并且所有的值也应该被保留。这怎么能在Perl中完成? 输出应该如下:

$VAR1 = { 
    def => { 
     659 => [ 
      'wx', 
      'yg', 
      'kl' 
     ], 
     456 => [ 
      'as', 
      'sd', 
      'df' 
     ] 
    }, 
    abc => { 
     987 => [ 
      'lk', 
      'dm', 
      'sd' 
     ], 
     123 => [ 
      'xx', 
      'yy', 
      'zy' 
     ], 
     456 => [ 
      'ab', 
      'cd', 
      'ef' 
     ] 
    } 
}; 
+0

你能给我一个合并后的数据的例子结构,例如在'%a =(key1 => {key2 => [1]})'和'%b =(key1 => {key2 => [1]})之间'当我不知道我要去哪里的时候,我不知道要走哪条路。 – amon

+0

我已经编辑了必要输出的主要问题,感谢您的帮助! –

回答

4
for my $x (keys(%h2)) { 
    for my $y (keys(%{ $h2{$x} })) { 
     push @{ $h1{$x}{$y} }, @{ $h2{$x}{$y} }; 
    } 
} 
+0

不起作用:'不能在XX行使用一个未定义的值作为ARRAY参考,' – Zaid

+0

@Zaid,虽然缺少美元符号,但我没有看到这个错误。固定。我不得不在未经测试的情况下冲出去,但现在的版本已经过测试。 – ikegami

+0

问题出在我身上...错误地重新标记了var名称 – Zaid

0
sub merge_hashes { 
    my ($h1, $h2) = @_; 
    foreach my $key (keys %$h2) { 
     if (!exists $h1->{$key} || ref($h1->{$key}) ne 'HASH' || ref($h2->{$key}) ne 'HASH') { 

      $h1->{$key} = $h2->{$key}; 
     } 
     else { 
      merge_hashes($h1->{$key}, $h2->{$key}); 
     } 
    } 
} 

merge_hashes(\%hash1, \%hash2); 
0

对提供的样本数据,下面将进行合并你描述:

my %merged = map { 
       $_ => { 
         %{$a{$_} // {}}, 
         %{$b{$_} // {}} 
        } 
      } (keys %a, keys %b); 

测试:

use strict; 
use warnings; 
use Data::Dump 'dd'; 

my %a = (
abc => { 
     123 => [ 
      'xx', 
      'yy', 
      'zy' 
     ], 
     456 => [ 
      'ab', 
      'cd', 
      'ef' 
     ] 
    } 
); 
my %b = (
def => { 
     659 => [ 
      'wx', 
      'yg', 
      'kl' 
     ], 
     456 => [ 
      'as', 
      'sd', 
      'df' 
     ] 
    }, 
    abc => { 
     987 => [ 
      'lk', 
      'dm', 
      'sd' 
     ] 
    } 
); 

my %merged = map { 
        $_ => { 
          %{$a{$_} // {}}, 
          %{$b{$_} // {}} 
         } 
       } (keys %a, keys %b); 

dd \%merged; 
# { 
# abc => { 
#   123 => ["xx", "yy", "zy"], 
#   456 => ["ab", "cd", "ef"], 
#   987 => ["lk", "dm", "sd"], 
#   }, 
# def => { 456 => ["as", "sd", "df"], 659 => ["wx", "yg", "kl"] }, 
# }