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'
        ]
    }
 };
4

4 回答 4

7

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

于 2012-09-24T14:53:51.617 回答
4
for my $x (keys(%h2)) {
    for my $y (keys(%{ $h2{$x} })) {
        push @{ $h1{$x}{$y} }, @{ $h2{$x}{$y} };
    }
}
于 2012-09-24T15:24:21.763 回答
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);
于 2012-09-24T15:17:32.000 回答
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"] },
# }
于 2012-09-24T15:24:59.237 回答