如何在Perl中合并哈希?

106
什么是将两个哈希合并到%hash1中的最佳方法?我始终知道%hash2和%hash1始终具有唯一的键。如果可能的话,我也更喜欢单行代码。
$hash1{'1'} = 'red';
$hash1{'2'} = 'blue';
$hash2{'3'} = 'green';
$hash2{'4'} = 'yellow';
4个回答

188

简要回答

    %hash1 = (%hash1, %hash2)
## 或者 ...
@hash1{keys %hash2} = values %hash2;
## 或使用引用 ...
$hash_ref1 = { %$hash_ref1, %$hash_ref2 };

概述

  • 背景: Perl 5.x
  • 问题: 用户希望将两个哈希1合并为一个变量

解决方案

  • 对于简单变量,使用上述语法
  • 对于复杂嵌套变量,使用Hash::Merge

注意事项

另请参阅

  • 网页搜索://perl合并哈希
  • https://metacpan.org/pod/Hash::Merge

  • 脚注

    1 *(又称关联数组,又称字典


    2
    是的,如果没有键冲突,@hash1{keys %hash2} = values %hash2; 是我所知道的最快和最短的方法。 - kixx
    48
    为什么不能直接执行 %hash1 = (%hash1, %hash2) - user102008
    1
    它似乎也可以使用引用:$hash_ref1 = ($hash_ref1, $hash_ref2); - lepe
    2
    这将把$hash_ref1设置为$hash_ref2,不进行合并。你想要$hash_ref1 = { %$hash_ref1, %$hash_ref2 };,我会编辑答案。 - M Somerville
    @MSomerville 但是合并操作将会创建一个新的哈希引用;当存在对该哈希的引用时,这可能是不正确的,对吗?也许应该使用 @$hash_ref1{ keys %$hash_ref2 } = values %$hash_ref2; - U. Windl

    40

    请查看perlfaq4:如何合并两个哈希表,其中有很多有用的信息可供使用,并且可以立即获得,而不必等待其他人回答它。 :)


    在决定合并两个哈希表之前,您必须决定如果两个哈希表都包含相同的键,要怎么处理这些键,并且是否想将原始哈希表保留为原样。

    如果要保留原始哈希表,请将其中一个哈希表(%hash1)复制到一个新哈希表(%new_hash),然后将另一个哈希表(%hash2)的键添加到新哈希表中。检查键是否已经存在于%new_hash中,这样您就有机会决定如何处理重复键:

    my %new_hash = %hash1; # make a copy; leave %hash1 alone
    
    foreach my $key2 ( keys %hash2 )
        {
        if( exists $new_hash{$key2} )
            {
            warn "Key [$key2] is in both hashes!";
            # handle the duplicate (perhaps only warning)
            ...
            next;
            }
        else
            {
            $new_hash{$key2} = $hash2{$key2};
            }
        }
    

    如果您不想创建一个新的哈希,仍然可以使用这个循环技巧;只需将 %new_hash 更改为 %hash1。

    foreach my $key2 ( keys %hash2 )
        {
        if( exists $hash1{$key2} )
            {
            warn "Key [$key2] is in both hashes!";
            # handle the duplicate (perhaps only warning)
            ...
            next;
            }
        else
            {
            $hash1{$key2} = $hash2{$key2};
            }
        }
    

    如果您不介意其中一个哈希覆盖另一个哈希的键和值,您可以使用哈希切片将一个哈希添加到另一个哈希中。在这种情况下,当具有相同键时,%hash2中的值将替换%hash1中的值:

    @hash1{ keys %hash2 } = values %hash2;
    

    很好,可以在其他问题中链接到perlfaq和其他资源。 - Chris

    17

    这是一个老问题,但在我搜索 "perl 合并哈希" 时排名很高 - 然而它并没有提到非常有用的 CPAN 模块 Hash::Merge


    1
    最高投票的答案已更新,包括此内容。 - dreftymac

    8

    对于哈希引用,您应使用以下方式的大括号:

    $hash_ref1 = {%$hash_ref1, %$hash_ref2};
    

    而不是上面使用括号的建议答案:

    $hash_ref1 = ($hash_ref1, $hash_ref2);
    

    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接