Tal*_*Guy 2 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' => '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");
}
Run Code Online (Sandbox Code Playgroud)
我期待得到的是:
size = 1600x1200,position = -25
size = 1280x1024,position = 25
size = 800x600,position = 0
我得到的是:
在连接(.)中使用未初始化的值$ size或在C:\ Test.pl第23行使用字符串.
在连接(.)中使用未初始化的值$ position或在C:\ Test.pl第23行使用字符串.
size =,position =
foreach语句显然是错误的,因为不仅没有$ size和$ position的值,它只经历了一次而不是三次.我尝试过各种变量前缀的变种,但没有找到可行的变量.
我究竟做错了什么?
Eth*_*her 14
首先,始终使用以下命令启动每个脚本或模块:
use strict;
use warnings;
Run Code Online (Sandbox Code Playgroud)
您将获得更多警告消息,这将有助于调试.
我无法复制您的错误:当我将该代码放入文件并运行它而没有其他标志时,我得到:size = , position =.您打印的代码中没有错误消息不匹配.$size变量,因此
但是,您正在声明您的数据结构不正确.散列和数组只能包含标量值,而不能包含列表:因此,如果要嵌套数组或散列,则需要将其作为引用.有关数据结构和参考的更多信息,请参阅perldoc perldata,perldoc perldsc 和perldoc perlreftut.
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");
}
Run Code Online (Sandbox Code Playgroud)
Jam*_*son 14
这是一些更新的代码,下面有一个解释:
#!/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");
}
}
Run Code Online (Sandbox Code Playgroud)
我已用方括号和大括号替换了一些括号.在Perl中,方括号为您提供对匿名数组的引用,而花括号表示对匿名哈希的引用.这些被称为匿名,因为匿名数组或散列没有明确的变量名.
由于Perl数据结构使您存储对哈希的引用而不是实际哈希,因此您需要使用这些引用来构造引用.您可以通过以下两个步骤执行此操作:
my @array = ( 1, 2, 3 );
my $array_ref = \@array;
my %hash = ( 'one' => 1, 'two' => 2, 'three' => 3 );
my $hash_ref = \%hash_ref;
Run Code Online (Sandbox Code Playgroud)
要从$ array_ref和$ hash_ref中获取数据,您需要 - >运算符:
print $array_ref->[0], "\n";
print $hash_ref->{one}, "\n";
Run Code Online (Sandbox Code Playgroud)
在引用散列键时,您不需要{}内部的引号,尽管有些人认为散列键上的引号是很好的做法.
我在整个数据结构中添加了一个迭代示例作为示例,而不仅仅是查看一个引用.这是第一行:
foreach my $name ( keys %photo_details ) {
Run Code Online (Sandbox Code Playgroud)
keys方法返回散列中的所有键,以便您可以按顺序获取它们.下一行迭代%photo_details中的所有photo_detail hashref:
foreach my $photo_detail ( @{ $photo_details{$photo} } ) {
Run Code Online (Sandbox Code Playgroud)
将@{ $photo_details{$photo} }引用取消引用$photo_details{$photo}到数组中,您可以使用foreach迭代它.
我添加的最后一件事是调用Data :: Dumper,这是一个与Perl一起分发的非常有用的模块,可以为您打印出数据结构.这在构建像这样的数据结构时非常方便,因为它与表达密切相关的Data :: Dumper :: Simple.遗憾的是,这个模块没有与Perl一起发布,但我更喜欢它的输出,因为它包含变量名.
有关如何使用引用构建复杂数据结构的进一步阅读,请查看perlreftut.