在Perl中遍历哈希值

4

我有一个哈希,里面有20个值。

它是这样初始化的:

my $line = $_[0]->[0];

    foreach my $value ($line) {
        print $value;
    }

现在,当我尝试获取$line中每个哈希值时,它会显示:

在file.pl的第89行打印时使用了未初始化的值

有没有一种方法可以遍历哈希的每个值?

我也尝试过以下方式:

my %line = $_[0]->[0];

    foreach my $key (keys %line) {
        print %line->{$key};
    }

但这也不起作用:在file.pl的第89行找到了一个参考,其中期望是偶数大小的列表

有人知道该怎么办吗?这不应该很难...


我有些困惑。看起来你初始化了一个标量,而不是哈希。 - Cascabel
在你的第二个例子中,你试图将它变成哈希表,但你仍然分配了一个标量 - 也许它是一个哈希引用? - Cascabel
使用Perl调试器并使用x命令打印出您的参数列表。 - tchrist
4个回答

12

遍历哈希表中的值:

for my $value (values %hash) {
  print $value;
}

3
首先,您必须理解哈希和哈希引用之间的区别。
您最初的赋值 $_[0]->[0] 的意思是:取当前函数的第一个参数($_[0]),对其进行取消引用操作(->),并将其视为数组并检索其第一个值([0])。该值不能是列表或哈希,它必须是标量(字符串、整数、浮点数、引用)。
以下是一些示例:
my %hash = ( MyKey => "MyValue");
my $hashref = \%hash;
# The next line print all elements of %hash
foreach (keys %hash) { print $_ }
# And is equivalent to
foreach (keys %{$hashref}) { print $_ }
$hash{MyKey} == $hashref->{MyKey}; # is true

请参考http://perldoc.perl.org/perlreftut.html获取更多详细信息。

不,$_[0] 不是一个函数。它是 @_ 数组的第一个(标量)元素。所以 $_[0]->[0] — 与 $_[0][0]${ $_[0] }[0] 相同 — 取 @_ 的第一个标量元素,将其解释为数组引用,并返回该被引用的数组的第一个元素。 - tchrist
从未说过$ _ [0]是一个函数。 - OMG_peanuts

3

$line在你的第一个例子中是一个标量,而不是哈希。

如果它是哈希引用,请使用%{$line}进行解引用。


1
啊,我明白了!现在它可以工作了:my $line = $_[0]->[0];foreach my $value (values %{$line}) { print $value . "\n"; } - baklap

2
警告提示你在$_[0]->[0]处没有任何内容。它并没有报错并告诉你正在操作一个空值,所以$_[0]很可能是一个数组引用,但是第一个位置上没有任何元素——或者它指向了一个空数组。
  • 如果是空字符串或0,则不会出现警告。
  • 如果有任何引用存在,则即使只打印BLAH(0x80af74),也能输出一些内容。(其中“BLAH”是“ARRAY”、“HASH”、“SCALAR”、“REF”、“GLOB”、“IO”等之一)

我建议你这样做:

use Data::Dumper;
say Data::Dumper->Dump( [ $_[0] ] ); # or even say Data::Dumper->Dump( [ \@_ ] )

接下来查看输出结果。

一旦你在$_[0]->[0]处获得了一个哈希引用,如果你必须遍历哈希表,最好的方法是:

while ( my ( $key, $value ) = each %$hashref ) { 
   do_stuff_with_key_and_value( $key, $value );
}

请查看each

最后,似乎您有一些符号混淆。请参见此链接的最后部分,以了解解释符号('$''@''%')不是变量名称的一部分,而是指示我们要从中检索什么内容的指示器。Perl compilation woes


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