Arrays 如何在散列中的数组中引用Perl散列?
这是我正在处理的代码片段:Arrays 如何在散列中的数组中引用Perl散列?,arrays,perl,hash,reference,perl-data-structures,Arrays,Perl,Hash,Reference,Perl Data Structures,这是我正在处理的代码片段: my %photo_details = ( 'black_cat' => ( ('size' => '1600x1200', 'position' => -25), ('size' => '1280x1024', 'position' => 25), ('size' => '800x600', 'position' => 0), ), 'race_car' => ( ('size' =&g
my %photo_details = (
'black_cat' => (
('size' => '1600x1200', 'position' => -25),
('size' => '1280x1024', 'position' => 25),
('size' => '800x600', 'position' => 0),
),
'race_car' => (
('size' => '1600x1200', 'position' => 10),
('size' => '800x600', 'position' => 5),
),
);
my $photo = 'black_cat';
foreach my $photo_detail ($photo_details{$photo})
{
my $size = $photo_detail{'size'};
my $position = $photo_detail{'position'};
print ("size = $size, position = $position\n");
}
我期望得到的是:
尺寸=1600x1200,位置=-25
大小=1280x1024,位置=25
尺寸=800x600,位置=0
我得到的是:
在C:\Test.pl第23行的串联(.)或字符串中使用未初始化的值$size
在C:\Test.pl第23行的串联(.)或字符串中使用未初始化的值$position
大小=,位置=
foreach语句显然是错误的,因为它不仅没有$size和$position的值,而且只循环了一次而不是三次。我尝试了各种各样的变量前缀,但没有发现一种是有效的
我做错了什么?首先,始终以以下内容开始每个脚本或模块:
use strict;
use warnings;
您将得到更多的警告消息,并且更快,这将大大有助于调试
我无法复制您的错误:当我将代码放入一个文件并在没有附加标志的情况下运行它时,我得到:size=,position=
。您打印的代码中没有$size
变量,因此错误消息不匹配
但是,您的数据结构声明不正确。散列和数组可以
只包含标量值,而不包含列表:因此如果要嵌套数组或
一个散列,你需要把它作为参考。看见
以及有关数据结构和引用的更多信息
my %photo_details = (
black_cat => [
{ size => '1600x1200', position => -25 },
{ size => '1280x1024', position => 25 },
{ size => '800x600', position => 0 },
],
race_car => [
{ size => '1600x1200', position => 10 },
{ size => '800x600', position => 5 },
],
);
foreach my $photo_detail (@{$photo_details{black_cat}})
{
my $size = $photo_detail->{size};
my $position = $photo_detail->{position};
print ("size = $size, position = $position\n");
}
以下是一些更新的代码,解释如下:
#!/usr/bin/perl
use strict;
use warnings;
use Data::Dumper;
my %photo_details = (
'black_cat' => [
{'size' => '1600x1200', 'position' => -25},
{'size' => '1280x1024', 'position' => 25},
{'size' => '800x600', 'position' => 0},
],
'race_car' => [
{'size' => '1600x1200', 'position' => 10},
{'size' => '800x600', 'position' => 5},
],
);
print Dumper( %photo_details );
foreach my $name ( keys %photo_details ) {
foreach my $photo_detail ( @{ $photo_details{$name} } ) {
my $size = $photo_detail->{'size'};
my $position = $photo_detail->{'position'};
print Dumper( $photo_details{$photo} );
print ("size = $size, position = $position\n");
}
}
我用方括号和花括号替换了你的一些括号。在Perl中,方括号表示对匿名数组的引用,而花括号表示对匿名哈希的引用。这些被称为匿名,因为匿名数组或散列没有显式的变量名
由于Perl数据结构使您存储对散列的引用,而不是实际的散列,因此您需要这些来构造引用。您可以通过以下两个步骤完成此操作:
my @array = ( 1, 2, 3 );
my $array_ref = \@array;
my %hash = ( 'one' => 1, 'two' => 2, 'three' => 3 );
my $hash_ref = \%hash_ref;
要从$array\u ref和$hash\u ref中获取数据,需要->运算符:
print $array_ref->[0], "\n";
print $hash_ref->{one}, "\n";
当引用哈希键时,您不需要{}内的引号,尽管有些人认为散列键上的引号是很好的做法。p> 我添加了一个对整个数据结构进行迭代的示例作为示例,而不仅仅是查看一个引用。这是第一行:
foreach my $name ( keys %photo_details ) {
keys方法返回散列中的所有键,以便按顺序获取它们。下一行迭代%photo\u details中的所有photo\u details hashref:
foreach my $photo_detail ( @{ $photo_details{$photo} } ) {
@{$photo\u details{$photo}
将引用$photo\u details{$photo}
反引用到一个数组中,您可以使用foreach对其进行迭代
我添加的最后一件事是调用,这是一个非常有用的模块,由Perl分发,可以为您打印数据结构。当构建这样的数据结构时,这是非常方便的,它的近亲也是如此。不幸的是,这个模块没有用Perl分发,但我更喜欢它的输出,因为它包含变量名
有关如何使用引用构建复杂数据结构的进一步阅读,请参阅 实际上只有一件事需要担心,那就是数据结构的顶层。之后,您只需为每个级别使用正确的索引语法: 如果您有一个常规散列,那么您可以访问所需的密钥,然后在该密钥之后为每个级别排列附加索引:
%regular_hash = ...;
$regular_hash{$key}[$index]{$key2};
如果您有一个引用,您可以做几乎相同的事情,但是您必须在顶级引用之后用箭头开始初始取消引用,->
。之后是相同的索引顺序:
$hash_ref = ...;
$hash_ref->{$key}[$index]{$key2};
有关所有详细信息,请参见我们在何处解释引用语法。我很困惑,$size肯定在他发布的代码片段中,您甚至将其带到了代码中。你什么意思?@雷克萨斯:是的,你说得对;我想这个错误可能是因为使用了
$photo\u detail->{$size}
vs$photo\u detail->{size}
。我完全忽略了my$size=…
声明。然而,我不能复制OP的错误。启用strictures后,代码会在前面的%photo\u detail
处出现条带(由于for循环未取消对数组的引用)。感谢您的解释。数据结构现在看起来确实不错。但是,如果我尝试上面的代码,我会在第20行和第21行得到“全局符号“%photo\u detail”需要显式的包名”。我阅读了文档(谢谢),将foreach语句更改为[foreach my$photo_detail(@{%photo_details->{black_cat}]),将
[$photo_detail{size}]更改为[$photo_detail->{size}],并将
[$photo_details{position position position}]更改为`[$photo_details->{positionforeach行上的“使用散列作为参考是不推荐的”。有什么想法吗?@我没有对你的逻辑提出错误,只有$size的语句让我感到困惑!OP似乎在学习符号和范围的使用。两者一开始都令人困惑。(+1,我给你一个好建议)@TallGuy:在“perldoc perlwarn”中查找警告消息是一种信息:您的foreach行有标点错误。您的意思是$photo\u details{$name}
?我的$hash\u ref=\%hash\u ref;
-那应该是\%hash
我这里只有一个问题:为了便于描述,我们可以将这个数据结构称为哈希数组的哈希吗?