如果你打开了use strict 和use warnings,你应该总是这样做,你会得到一堆关于未声明变量的致命错误。让我们先解决这些问题:
use strict;
use warnings;
use JSON;
my $test='{
"name":"Tony",
"body":[ {
"arms":["hands:fingers", "muscles:biceps"],
"stomach":["abs:sixpack", "noabs:onepack"]
},
{
"arms":["fingers:nails", "knuckles:sharp"],
"stomach":["abs:gut", "noabs:liquor"]
}]
}';
my $decoded = decode_json($test);
my @layer1 = @{ $decoded->{'body'} };
foreach ( @layer1 ) {
my @layer2 = $_->{$decoded->{'arms'} };
foreach( @layer2 ) {
print $_->{$decoded->{'hands'}} . "\n";
}
}
现在,至少代码将在use strict 下编译。但它会发出一堆警告:
Use of uninitialized value in hash element at js.pl line 21.
Use of uninitialized value in hash element at js.pl line 23.
Use of uninitialized value in concatenation (.) or string at js.pl line 23.
Use of uninitialized value in hash element at js.pl line 21.
Use of uninitialized value in hash element at js.pl line 23.
Use of uninitialized value in concatenation (.) or string at js.pl line 23.
这些警告是有用的信息! use warnings 是多么有用的工具啊!
我们来看第一个:js.pl 第21行hash元素中未初始化值的使用。
第 21 行是:
my @layer2 = $_->{$decoded->{'arms'} };
在此循环中,$_ 设置为外部数组的每个元素 (@{ $decoded->{body} })。该数组的每个元素都是一个哈希引用。您正在做的是尝试使用散列 第一级 中的键 arms 作为数组中元素指向的散列的键。这些散列中不存在该键,这就是为什么您会收到有关未初始化值的警告的原因。
要得到我们想要的,我们只需要
my @layer2 = @{ $_->{arms} };
现在第三层更复杂了;它是一个以冒号分隔的字符串数组,而不是一个哈希数组。在那个循环中,我们可以丢弃我们不想要的字符串,直到找到hands
foreach( @layer2 ) {
next unless /^hands:/;
my ( $thing, $other_thing ) = split /:/, $_;
print $other_thing, "\n";
}
这是固定的脚本:
use strict;
use warnings;
use JSON;
my $test='{
"name":"Tony",
"body":[ {
"arms":["hands:fingers", "muscles:biceps"],
"stomach":["abs:sixpack", "noabs:onepack"]
},
{
"arms":["fingers:nails", "knuckles:sharp"],
"stomach":["abs:gut", "noabs:liquor"]
}]
}';
my $decoded = decode_json($test);
my @layer1 = @{ $decoded->{'body'} };
foreach ( @layer1 ) {
my @layer2 = @{ $_->{arms} };
foreach( @layer2 ) {
next unless /^hands:/;
my ( $thing, $other_thing ) = split /:/, $_;
print $other_thing, "\n";
}
}
输出:
fingers
有关在 Perl 中处理复杂结构的更多信息,请参阅以下内容:
阅读它们,再阅读它们,然后编写代码。然后再读一遍。