2012-11-06 37 views
3

有一个问题,解释正是我想在这里:how to merge 2 deep hashes in perl结合2+“深”(多维)散列在Perl

然而,答案似乎有不为我工作(建议使用Merge模块)。

我有两个哈希值,像这样:

$VAR1 = { 
      '57494' => { 
         'name' => 'John Smith', 
         'age' => '9', 
         'height' => '120' 
        }, 
      '57495' => { 
         'name' => 'Amy Pond', 
         'age' => '17', 
         'height' => '168' 
        } 
     } 
}; 
$VAR1 = { 
      '57494' => { 
         'name_address' => 'Peter Smith', 
         'address' => '5 Cambridge Road', 
         'post_code' => 'CR5 0FS' 
        } 
     } 
}; 

如果我使用Hash::Merge%c = {%a,%b}格式每次都是这样,我得到:

$VAR1 = '57494'; 
$VAR2 = { 
      'name_address' => 'Peter Smith', 
      'address' => '5 Cambridge Road', 
      'post_code' => 'CR5 0FS' 
     }; 

(因此,它基本上与第二改写第一数据并且弄乱了键)当我想要时:

$VAR1 = { 
      '57494' => { 
         'name' => 'John Smith', 
         'age' => '9', 
         'height' => '120' 
         'name_address' => 'Peter Smith', 
         'address' => '5 Cambridge Road', 
         'post_code' => 'CR5 0FS' 
        }, 
      '57495' => { 
         'name' => 'Amy Pond', 
         'age' => '17', 
         'height' => '168' 
        } 
     } 
}; 

因此,当密钥相同时,数据会合并在一起,否则新密钥将被添加到结尾。我希望这是有道理的。也许我使用Merge错误地做了一些事情,或者需要'手动'将它们添加到循环中,但是我花了太多时间思考它,无论如何!

编辑:我如何使用合并,看看我在做一些愚蠢的:

我:

use Hash::Merge qw(merge); 

...hash data above as %hash1 and %hash2... 

my %combined_hash = %{ merge(%hash1,%hash2) }; 
print Dumper(%combined_hash); 
+1

我不知道。我使用[**'Hash :: Merge' **](http://search.cpan.org/perldoc?Hash::Merge)或[**'Hash :: Merge :: Simple']来获得所需的结果。 **](http://search.cpan.org/perldoc?Hash::Merge::Simple)。 – Axeman

+0

向我们展示代码! –

+0

您示例数据中的'}'太多了...... – simbabque

回答

6

如果我用引用来做,它就像一个魅力。

use strict; use warnings; 
use Data::Dumper; 
use Hash::Merge qw(merge); 
my $h1 = { 
    '57494' => { 
    'name' => 'John Smith', 
    'age' => '9', 
    'height' => '120' 
    }, 
    '57495' => { 
    'name' => 'Amy Pond', 
    'age' => '17', 
    'height' => '168' 
    } 
}; 

my $h2 = { 
    '57494' => { 
    'name_address' => 'Peter Smith', 
    'address'  => '5 Cambridge Road', 
    'post_code' => 'CR5 0FS' 
    } 
}; 

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

输出:

$VAR1 = { 
     '57495' => { 
        'name' => 'Amy Pond', 
        'age' => '17', 
        'height' => '168' 
       }, 
     '57494' => { 
        'name_address' => 'Peter Smith', 
        'name' => 'John Smith', 
        'post_code' => 'CR5 0FS', 
        'address' => '5 Cambridge Road', 
        'height' => '120', 
        'age' => '9' 
       } 
    }; 

但是,如果我用哈希散列而不是裁判做到这一点,它不:

my %hash1 = (
    '57494' => { 
    'name' => 'John Smith', 
    'age' => '9', 
    'height' => '120' 
    }, 
    '57495' => { 
    'name' => 'Amy Pond', 
    'age' => '17', 
    'height' => '168' 
    } 
); 

my %hash2 = (
    '57494' => { 
    'name_address' => 'Peter Smith', 
    'address'  => '5 Cambridge Road', 
    'post_code' => 'CR5 0FS' 
    } 
); 

my %h3 = merge(%hash1, %hash2); 
print Dumper \%h3; 

__END__ 
$VAR1 = { 
    '57495' => undef 
}; 

这是因为mergeHash::Merge能只有参考,但你传递它的哈希值。另外,您需要在标量上下文中调用它

尝试它像这样:

#        +--------+--- references 
# ,-- SCALAR context  |  | 
my $combined_hash = %{ merge(\%hash1, \%hash2) }; 
print Dumper($combined_hash); 
+0

啊你知道,我有我的原始版本作为参考,但这样做: '我%h3 =%{合并($ h1,$ h2)};'但是当我改变它为纯引用,它似乎工作。奇怪的! 我觉得有点傻,我错过了尝试这种组合,但谢谢你让我清楚! – dgBP

+0

@bladepanthera它有一个错误。关键字(不是散列键)是引用两个参数散列,但要在标量上下文中调用它。你需要'$ combined_hash',而不是'%combined_hash'。然后你可以引用你传递给'merge'的哈希,并且不需要把它们放在引用变量中。 – simbabque

+0

你明白了。谢谢 – dgBP

1
for my $key (keys %fromhash) { 
    if(not exists $tohash{$key}) { 
     $tohash{$key} = {}; 
    } 
    for my $subkey (keys %{$fromhash{$key}}) { 
     ${$tohash{$key}}{$subkey} = ${$fromhash{$key}}{$subkey}; 
    } 
} 

随着这取决于我的最后的咖啡是否是任何或多或少牙套好。

的Python绝对是这种事情更舒适,因为它不会让你想引用:

for key in fromdict: 
    if key not in todict: 
     todict[key] = {} 
    todict[key] = dict(fromdict[key].items() + todict[key].items()) 

或者,如果todictdefaultdict(创建上阅读以及分配键):

for key in fromdict: 
    todict[key] = dict(dict(fromdict[key]).items() + dict(todict[key]).items()) 
+0

我没有得到咖啡的参考。 – simbabque

+2

然后你还没有足够的咖啡。 –

+2

事实上,在第5行中还需要一个大括号:'keys%{$ fromhash {$ key}})'。我会坚持约克郡茶。 =) – simbabque