散列合并/连接

时间:2012-09-24 14:42:23

标签: perl hash merge concatenation

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

4 个答案:

答案 0 :(得分:7)

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

答案 1 :(得分:4)

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

答案 2 :(得分: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);

答案 3 :(得分: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"] },
# }