如何在Perl中结合散列?


95

将两个哈希值合并到%hash1的最佳方法是什么?我一直都知道%hash2和%hash1总是有唯一的键。如果可能的话,我也希望使用一行代码。

$hash1{'1'} = 'red';
$hash1{'2'} = 'blue';
$hash2{'3'} = 'green';
$hash2{'4'} = 'yellow';

Answers:


168

快速解答(TL; DR)

    %hash1 =(%hash1,%hash2)

    ## 要不然 ...

    @ hash1 {键%hash2} =值%hash2;

    ##或带参考...

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

总览

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

  • 对简单变量使用上面的语法
  • 使用Hash :: Merge处理复杂的嵌套变量

陷阱

也可以看看


脚注

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


2
是的,如果没有按键冲突,则@ hash1 {keys%hash2} =值%hash2; 是最快和最短的方法,AFAIK。
kixx

46
您为什么不能做%hash1 = (%hash1, %hash2)
user102008 2010年

1
它似乎也可以与引用一起使用:$ hash_ref1 =($ hash_ref1,$ hash_ref2);
lepe

2
它将设置$hash_ref1$hash_ref2,不合并。您想要$hash_ref1 = { %$hash_ref1, %$hash_ref2 };,我将编辑答案。
M萨默维尔

38

查看perlfaq4:如何合并两个哈希。Perl文档中已经有很多好的信息,您可以立即获取它,而不必等待其他人回答。:)


在决定合并两个哈希之前,必须确定如果两个哈希都包含相同的键,并且要保留原始哈希不变,该怎么办。

如果要保留原始哈希,请将一个哈希(%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以及其他问题的其他资源
克里斯,克里斯

14

这是一个古老的问题,但是在我的Google搜索“ perl merge hash”中排名很高-但它没有提到非常有用的CPAN模块Hash :: Merge


投票最多的答案已更新为包含此内容。
dreftymac

6

对于哈希引用。您应该使用如下花括号:

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

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

$hash_ref1 = ($hash_ref1, $hash_ref2);
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.