合并包含公共键和值的散列,perl

合并包含公共键和值的散列,perl,perl,hash,merge,Perl,Hash,Merge,例如,我们有两个哈希。我们不知道它们的大小,但我们知道它们有共同的数据 %h1 = ( k1 => (a => "a1", b => "b1"), k2 => (a => "a2", b => "b2") k3 => (a => "a3", b => "b3"), k4 => (a => "a4", b =>

例如,我们有两个哈希。我们不知道它们的大小,但我们知道它们有共同的数据

%h1 = (
    k1 => (a => "a1",
           b => "b1"),
    k2 => (a => "a2",
           b => "b2")
    k3 => (a => "a3",
           b => "b3"),
    k4 => (a => "a4",
           b => "b4")
);
%h2 = (
    k2 => (c => "c2",
           b => "b2"),
    k3 => (c => "c3",
           b => "b3")
    k4 => (c => "c4",
           b => "b")
)
如何合并它们来得到这样的东西? 请注意,确切的键是未知的,但具有公共键值

%h3 = (
        k1 => (a => "a1",
               b => "b1",
               c => "0"),
        k2 => (a => "a2",
               b => "b2",
               c => "c2"),
        k3 => (a => "a3",
               b => "b3",
               c => "c3"),
        k4 => (a => "a4",
               b => "b4",
               c => "c4")
    )

您可以尝试以下方法:

use strict;
use warnings;
use Data::Dumper;
$Data::Dumper::Terse = 1;

my %h1 = (
    k1 => {a => "a1",
           b => "b1"},
    k2 => {a => "a2",
           b => "b2"},
    k3 => {a => "a3",
           b => "b3"},
    k4 => {a => "a4",
           b => "b4"}
);
my %h2 = (
    k2 => {c => "c2",
           b => "b2"},
    k3 => {c => "c3",
           b => "b3"},
    k4 => {c => "c4",
           b => "b"}
);

my $h3 = merge( \%h1, \%h2 );
print Dumper( $h3 );

sub merge {
    my ( $h1, $h2 ) = @_;

    my @keys = keys %{ {map {$_ => 1} keys %$h1, keys %$h2} };
    my @sub_keys = keys %{ {map {$_ => 1} map { keys %{ $_ } } values %$h1, values %$h2} };

    my %h;
    for my $k1 (@keys) {
        for my $k2 (@sub_keys) {
            $h{$k1}{$k2} = $h1->{$k1}{$k2} // $h2->{$k1}{$k2} // "0";
        }
    }
    return \%h;
}
输出

{      
  'k1' => {
            'b' => 'b1',
            'c' => '0',
            'a' => 'a1'
          },
  'k2' => {
            'a' => 'a2',
            'b' => 'b2',
            'c' => 'c2'
          },
  'k3' => {
            'c' => 'c3',
            'b' => 'b3',
            'a' => 'a3'
          },
  'k4' => {
            'a' => 'a4',
            'c' => 'c4',
            'b' => 'b4'
          }
}
试试这个

my %h3;
for my $k1 (keys %h1)
{

     $h3{$k1} = ($h2{$k1})?\(%{$h1{$k1}},%{$h2{$k1}}):\%{$h1{$k1}};
     delete $h2{$k1};   
}

for my $k2 (keys %h2)
{
    $h3{$k2} = \%{$h2{$k2}};
}

print Dumper \%h3;

注意:
%h2
键被删除。如果您想要
%h2
值,请在循环之前复制一份

如果值不同怎么办?例如,
$h1{k1}{a}eq'a1'
$h2{k1}{a}eq'a9'
另请参见,为了使用Hash::Merge,您还需要将子哈希放在大括号而不是圆括号中。这里是已经开发(和调试)的模块。他们节省时间。很多时间。。。