【问题标题】:Adding hashes to an array (Perl)向数组添加哈希 (Perl)
【发布时间】:2021-05-06 00:19:44
【问题描述】:

我有一个数组和哈希定义为:

my @test_array;

my %test_hash = (
    line_1 => 1,
    line_2 => 2,
    line_3 => 3,
);

我想将该哈希添加到数组中,然后修改哈希并将任何新版本推送到数组中

push (@test_array, %test_hash);

$test_hash{line_1} = 2;
push (@test_array, %test_hash);

最后,我需要在传入数组中的每个哈希时调用一个方法,一次一个:

for my $hash (@test_array) {
    $self->do_thing(%$hash)
}

但是,当我打印出数组时,似乎两个哈希都存储在一个元素中:

use Data::Dumper;
print Dumper (\@test_array);

### Begin Output ###
$VAR1 = [
          'line_1',
          1,
          'line_3',
          3,
          'line_2',
          2,
          'line_1',
          2,
          'line_3',
          3,
          'line_2',
          2
        ];

我的方法调用本质上应该如下所示,line_1 => 2 在第二次循环中的散列中:

$self->do_thing(
    line_1 => 1,
    line_2 => 2,
    line_3 => 3,
);

有人能解释一下为什么这一切都被添加到一个数组元素中吗?我希望 Dumper 输出将包含一个用于第一个推送哈希的 $VAR1 和一个用于第二个哈希的 $VAR2 - 但事实并非如此。

谢谢!

【问题讨论】:

  • 哈希和数组只能包含标量,不能包含哈希和数组。作为一种“解决方法”,我们将哈希和数组的引用存储在哈希和数组中,因为它们是标量。

标签: arrays perl dereference


【解决方案1】:

您不能向数组添加哈希,但可以添加对哈希的引用:

push @array, \%hash;

所有引用都是标量,列表是标量的集合。数组是一个包含列表的变量。

并且,当您想将数据结构传递给子例程并保持其完整时(因此,没有像您在此处看到的那样列出它),请传递引用。由于子程序得到了引用,所以可以直接改变hash。

$self->do_thing($hash);

现在是棘手的部分。在您的问题中间,您谈到了更新哈希。我认为您可能指的是两件事。

  1. 由于您有对哈希的引用,因此您对原始哈希所做的任何更改对引用都是可见的。它们指向相同的数据。

  2. 如果你想创建一个新的哈希来添加到数组中(除了你刚刚添加的那个),你需要做更多的工作。如果您想要同一事物的不同版本,您可以克隆哈希。 Storable 随 Perl 一起提供,并为此提供了 dclone 函数:

    use Storable qw(dclone);

    my %hash = ...;

    # now you have a completely disconnected copy (deep copy)
    push @array, dclone(\%hash);

    # change the hash. The reference in `@array` is not affected
    $hash{foo} = ...;
    
    # add an additional deep copy clone
    push @array, dclone(\%hash);

所有这些都在Intermediate Perl 以及诸如Perl Data Structures Cookbook 之类的文档中进行了介绍。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-01-07
    • 2020-06-30
    • 2022-07-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多