19

我对 Perl 还很陌生,所以如果这似乎是一个简单的问题,请原谅我......

无论如何,我有一个数组散列,我试图检索散列中的一个数组,但我能得到的只是数组的标量大小。

%HoA = a hash of arrays
$key = some key in the hash

foreach $nextItem (@HoA{$key}) {
  do a bunch of stuff with $nextItem
}

当我这样做时, $nextItem 总是只是数组的大小,并且循环只运行一次。我尝试打印以下内容:

@HoA{$key}
$HoA{$key}
@$HoA{$key}

前两个给我标量大小,第三个给我什么......我在这里错过了什么?

更新:我想知道我的问题是否实际上是我将数组添加到哈希的方式。这就是我正在做的事情:

@HoA{$key} = split(/ /, $list);

这会将数组粘贴在哈希中,还是将数组大小粘贴在哈希中?

更新2:我尝试了以下代码块:

my $key = "TEST";
my %HoA = ();
my @testarray = (1, 2, 3);
@HoA{$key} = @testarray;
print Dumper(%HoA);

这是输出:

$VAR1 = 'TEST';
$VAR2 = 1;

为什么它只粘贴数组的第一个值?

4

4 回答 4

19

尝试以这种方式引用您的数组:

%HoA = a hash of arrays
$key = some key in the hash

foreach $nextItem (@{$HoA{$key}}) {
  do a bunch of stuff with $nextItem
}

您将数组引用设置$HoA{$key}为数组。

编辑:对于您的更新,我认为您会得到您想要的,如果您这样做:

@{$HoA{$key}} = split(/ /, $list);

或者你可以做

push(@{$HoA{$key}}, split(/ /, $list);

例如:

my $list = "fred joe brown sam";
my %HoA = ();
my $key = "jacob";
@{$HoA{$key} = split(/ /, $list);
foreach my $item (@{$HoA{$key}})
{
    print "Test item: $nextItem\n";
}

You will get:
Test item: fred
Test item: joe
Test item: brown
Test item: sam

编辑:添加use strict;到程序的顶部。基本上,当您定义了哈希时,您会尝试将 HoA 用作数组。您不正确地引用了哈希的内容。要正确地做到这一点,你真的需要在and$之间有一个。Perl 是无类型的,如果你不这样做,它会让你逍遥法外。oreilly的参考摘录可能会澄清一些事情。@HoAuse strict;

my @testarray是一个数组
my %hash是一个散列
$hash{$el1} = \@array是一个散列元素,它具有一个数组的引用值
@{$hash{$el1}} = @array是一个包含一个数组的散列元素

于 2012-09-21T17:37:52.503 回答
11

哈希中的每个条目都是对数组的引用。例如:

$my_hash{$key}

是对数组的引用,而不是数组。$my_hash{$key}只是指向该数组所在的内存区域。要取消引用它,请将数组符号放在前面:

@{ my_hash{$key} }

当我们开始谈论元素时,事情变得有点棘手:

${ my_hash{$key} }[0]

是该数组的第一个元素。您可以想象,如果该数组由其他数组的散列组成,那么语法会变得非常晦涩。幸运的是,Perl 有一种简洁的处理方式:

$my_hash{$key}->[0];

这与上面完全相同,但更易于理解语法。有时,使用中间变量更容易,这样您就可以在没有所有取消引用的情况下引用事物:

my %hash_of_array_refs;

foreach my $key (sort keys %hash_of_array_refs) {
    my @array = @{ $hash_of_array_refs{$key} };    #Dereference
    foreach my $element (@array) {                 #Much easier to read and understand
        say "First element is $array[0]";
        say "last element is $array[$#array]";
        say "This element: $element";
    }
}

不取消引用你会得到这个:

my %hash_of_array_refs;

foreach my $key (sort keys %hash_of_array_refs) {
    foreach my $element (@{ $hash_of_array_refs{$key} } ) {                 #Much easier to read and understand
        say "First element is " . $hash_of_array_refs->[0];
        say "last element is " . $hash_of_array_refs->[$#{ $hash_of_array_refs{key} } ]";
        say "This element: $element";
    }
}
于 2012-09-21T20:25:40.283 回答
3
@array

是你如何得到数组,所以

@{ $array_ref }

与数组引用等效。

$HoA{$key}

是对数组的引用,所以

@{ $HoA{$key} }

是那个数组。

for my $nextItem (@{ $HoA{$key} }) 
于 2012-09-21T17:40:40.323 回答
1

“为什么只插入数组的第一个值?”

您需要通过在哈希前面加上反斜杠来将对数组的引用放入哈希中:

$HoA{$key} = \@testarray;

然后,当您从取消引用的哈希中检索它时:

@testarray = @{ $HoA{$key} };
于 2012-09-22T16:29:38.407 回答