我该如何在Perl中创建哈希数组并遍历它们?

4
我想创建一个哈希数组,但是在循环数组时遇到了问题。我尝试了以下代码,但它无法正常工作:
for  ($i = 0; $i<@pattern; $i++){
  while(($k, $v)= each $pattern[$i]){
    debug(" $k: $v");
  }
}
3个回答

24

首先,为什么你没有使用 strictwarnings?以下代码应该出现在每个 Perl 程序的顶部,在 #!/usr/bin/perl 之后。始终如此

use strict;
use warnings;

我知道你没有这么做,因为我相信在使用strictwarnings时,你会从很多其他代码中得到一些好的错误信息,而且根据你对变量的使用情况来判断。

其次,你为什么不这样做:

for my $i (@pattern) {
  ..
}

该循环遍历@pattern中的每个元素,逐一将它们分配给$i。然后,在您的循环中,当您需要特定的元素时,只需使用$i。对$i的更改将反映在@pattern中,当循环退出时,$i将超出范围,从而实际上清理自己。

第三点,请为了Larry Wall的爱,使用my声明变量以进行本地化。这真的不难,而且我保证这会让您成为一个更好的人。

第四点也是最后一点,您的数组存储对哈希的引用,而不是哈希本身。如果它们存储了哈希,则您的代码将是错误的,因为哈希以%开头,而不是$。就现在而言,引用(任何类型)都是标量值,因此以$开头。因此,我们需要取消引用它们以获取哈希:

for my $i (@pattern) {
  while(my($k, $v) = each %{$i}) {
    debug(" $k: $v");
  }
}

或者,你的方式:

for  (my $i = 0; $i<@pattern; $i++) { # added a my() for good measure
  while(my($k, $v) = each %{$pattern[$i]}) {
    debug(" $k: $v");
  }
}

哈哈,谢谢你的回答,即使读了很多内容才找到答案 :p 我要找的是 %{$i}(或者%{$_} 来重新获得我 Perl 的荣誉)。 - Marius
1
仅供参考,括号并不是必须的 - 在这种情况下,你可以写成%$i。我使用括号的原因是,如果你比$i更复杂,你需要它们:%{$pattern[$i]}不能写成%$pattern[$i],因为后者是有歧义的。 - Chris Lutz

6
尝试使用这个替代方案:
for my $hashref (@pattern) {
    for my $key (keys %$hashref) {
        debug "$key: $hashref->{$key}";
    }
}

你尝试的最大问题是each $pattern[$i]each函数需要一个哈希表来进行操作,但是$pattern[$i]返回一个哈希表引用(即哈希表的引用)。你可以通过将$pattern[$i]作为哈希表解引用来修复代码:
while(my($k, $v) = each %{$pattern[$i]}) {

此外,请注意each函数,它可能会使哈希迭代器处于不完整状态。

1
打败我11秒。也许我应该少唠叨一些。 - Chris Lutz
我试图快速发布,然后回来胡言乱语。 - Chas. Owens
这是一个很好的策略。我确实有很多东西要学习。此外,关于为什么each()不好的文章很有趣。我喜欢你的《星球大战》参考。 - Chris Lutz
1
each函数并不是坏的,而是危险的。keys函数也不完全安全:my @keys = keys %hash。如果%hash是一个绑定了dbm的哈希表,它所包含的数据量远远超过内存容量怎么办?在这种情况下,while (my ($key, $val) = each %hash) {}显然更为优越。 - Chas. Owens

4

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