如何在哈希中引用数组中的Perl哈希?

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,po​​sition = -25

size = 1280x1024,position = 25

size = 800x600,po​​sition = 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 perldscperldoc 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)

  • 好的建议和解释.我要补充的是,以下内容在调试Perl数据结构问题时非常有用:使用Data :: Dumper; 打印翻斗车(\%photo_details); (3认同)

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.