是否可以将键值对直接推送到 perl 中的哈希?

Is it possible to push a key-value pair directly to hash in perl?

我知道 pushing 只能传递给数组,不能传递给散列。但是允许将键值对直接推送到散列会方便得多(我仍然很惊讶这在 perl 中是不可能的)。我有一个例子:

#!/usr/bin/perl -w

#superior words begin first, example of that word follow
my @ar = qw[Animals,dog Money,pound Jobs,doctor Food];
my %hash;
my $bool = 1;

sub marine{
    my $ar = shift if $bool;
    for(@$ar){
        my @ar2 = split /,/, $_;
        push %hash, ($ar2[0] => $ar2[1]);
    }
}

marine(\@ar);
print "$_\n" for keys %hash;

这里我有一个数组,里面有2个单词,用,逗号分开。我想从它做一个散列,使第一个成为键,第二个成为值(如果它缺少值,就像最后一个 Food 字一样,那么根本没有值 -> 只是 undef。如何在 perl 中制作它?

输出:

Possible attempt to separate words with commas at ./a line 4.
Experimental push on scalar is now forbidden at ./a line 12, near ");"
Execution of ./a aborted due to compilation errors.

我可能把这里的事情简单化了,但为什么不简单地分配到哈希而不是试图推入它呢?

即替换这个不受支持的表达式:

push %hash, ($ar2[0] => $ar2[1]);

与:

$hash{$ar2[0]} = $ar2[1];

如果我将它合并到您的代码中,然后在最后转储生成的哈希值,我得到:

$VAR1 = {
          'Food' => undef,
          'Money' => 'pound',
          'Animals' => 'dog',
          'Jobs' => 'doctor'
        };

map 内拆分并直接分配给散列,如下所示:

my @ar = qw[Animals,dog Money,pound Jobs,doctor Food];
my %hash_new = map { 
                      my @a = split /,/, $_, 2; 
                      @a == 2 ? @a : (@a, undef) 
                   } @ar;

请注意,这也可以处理具有多个逗号分隔符的情况(因此最多拆分为 2 个元素)。这也可以处理没有逗号的情况,例如 Food - 在这种情况下,返回具有单个元素加上 undef 的列表。

如果您需要 push 多个 key/value 对到(另一个)哈希,或合并哈希,您可以分配一个哈希列表,如下所示:

%hash = (%hash_old, %hash_new);

请注意,旧哈希中的 相同 键将被新哈希覆盖。

我们可以将这个数组分配给一个散列,然后 perl 会自动查看数组中的值,就好像它们是 key-value 对一样。奇数元素(第一、第三、第五)将成为键,偶数元素(第二、第四、第六)将成为相应的值。检查 url https://perlmaven.com/creating-hash-from-an-array

use strict;
use warnings;
use Data::Dumper qw(Dumper);

my @ar;
my %hash;

#The code in the enclosing block has warnings enabled, 
#but the inner block has disabled (misc and qw) related warnings.
{
    #You specified an odd number of elements to initialize a hash, which is odd, 
    #because hashes come in key/value pairs.
     no warnings 'misc';
     #If your code has use warnings turned on, as it should, then you'll get a warning about 
     #Possible attempt to separate words with commas
     no warnings 'qw';
     @ar = qw[Animals,dog Money,pound Jobs,doctor Food];
     # join the content of array with comma => Animals,dog,Money,pound,Jobs,doctor,Food
     # split the content using comma and assign to hash
     # split function returns the list in list context, or the size of the list in scalar context.
     %hash = split(",", (join(",", @ar)));
}

print Dumper(\%hash);

Output

$VAR1 = {
          'Animals' => 'dog',
          'Money' => 'pound',
          'Jobs' => 'doctor',
          'Food' => undef
        };