如何在Perl中组合哈希?

mle*_*amp 92 perl hash merge dictionary

将两个哈希值合并到%hash1的最佳方法是什么?我总是知道%hash2和%hash1总是有唯一的密钥.如果可能的话,我也更喜欢一行代码.

$hash1{'1'} = 'red';
$hash1{'2'} = 'blue';
$hash2{'3'} = 'green';
$hash2{'4'} = 'yellow';
Run Code Online (Sandbox Code Playgroud)

dre*_*mac 162

快速回答(TL; DR)


    %hash1 = (%hash1, %hash2)

    ## or else ...

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

    ## or with references ...

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

概观

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

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

陷阱

  • 当两个哈希包含一个或多个重复键时,该怎么办?
    • 具有空值的键值对是否会覆盖具有非空值的键值对?
    • 什么构成空的与非空的价值首先?(例如undef,零,空字符串false,虚假......)

也可以看看


脚注

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

  • 为什么你不能只做`%hash1 =(%hash1,%hash2)` (46认同)
  • 是的,如果没有密钥冲突,@ hash1 {keys%hash2} = values%hash2; 是最快最短的方式,AFAIK. (2认同)
  • 那会将`$ hash_ref1`设置为`$ hash_ref2`,不合并。您想要`$ hash_ref1 = {%$ hash_ref1,%$ hash_ref2};`,我将编辑答案。 (2认同)

bri*_*foy 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};
        }
    }
Run Code Online (Sandbox Code Playgroud)

如果您不想创建新哈希,您仍然可以使用此循环技术; 只需将%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};
        }
    }
Run Code Online (Sandbox Code Playgroud)

如果您不关心一个哈希值会覆盖另一个哈希值中的键和值,您可以使用哈希切片将一个哈希值添加到另一个哈希值.在这种情况下,%hash2中的值在它们具有共同键时会替换%hash1中的值:

@hash1{ keys %hash2 } = values %hash2;
Run Code Online (Sandbox Code Playgroud)


Lee*_*Gee 14

这是一个老问题,但出来的高我在谷歌搜索"的Perl合并哈希" -但它没有提及非常有帮助CPAN模块的Hash ::合并


Jea*_*ieJ 5

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

$hash_ref1 = {%$hash_ref1, %$hash_ref2};
Run Code Online (Sandbox Code Playgroud)

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

$hash_ref1 = ($hash_ref1, $hash_ref2);
Run Code Online (Sandbox Code Playgroud)