【问题标题】:Hash merge/concatenation哈希合并/连接
【发布时间】:2012-09-16 01:11:33
【问题描述】:

这是我的哈希转储:%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'
        ]
    }
 };

【问题讨论】:

  • 你能给我一个合并数据结构的例子吗,例如在%a = (key1 => {key2 => [1]})%b = (key1 => {key2 => [1]}) 之间?当我不知道自己要去哪里时,我不知道该走哪条路。
  • 我已经用必要的输出编辑了主要问题,感谢您的帮助!!

标签: perl hash merge concatenation


【解决方案1】:

使用 CPAN 模块 Hash::MergeHash::Merge::Simple。第一个是高度可配置的,第二个是非常易于使用的。

【讨论】:

    【解决方案2】:
    for my $x (keys(%h2)) {
        for my $y (keys(%{ $h2{$x} })) {
            push @{ $h1{$x}{$y} }, @{ $h2{$x}{$y} };
        }
    }
    

    【讨论】:

    • 不起作用:Can't use an undefined value as an ARRAY reference at - line XX
    • @Zaid,尽管缺少美元符号,但我没有收到该错误。固定的。之前没测试就冲出去了,不过现在的版本已经测试过了。
    • @Zaid,总是use strict; use warnings; :) ;)
    • strictwarnings 如果您使用 %h1 而不是 %h2,请不要抱怨 :)
    • @Dheeraj,当然,最后。因为我要合并到%h1,所以它会是print(Dumper(\%h1));
    【解决方案3】:

    对于提供的示例数据,以下将执行您描述的合并:

    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"] },
    # }
    

    【讨论】:

      【解决方案4】:
      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);
      

      【讨论】:

        猜你喜欢
        • 2018-06-17
        • 2017-07-13
        • 1970-01-01
        • 1970-01-01
        • 2012-08-19
        • 2011-02-21
        • 1970-01-01
        • 1970-01-01
        • 2014-04-16
        相关资源
        最近更新 更多