【问题标题】:How do I parse a 3D JSON array in Perl?如何在 Perl 中解析 3D JSON 数组?
【发布时间】:2013-09-16 07:44:28
【问题描述】:
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 ) {
    @layer2 = $_->{$decoded->{'arms'} };
   foreach( @layer2 ) {
     print $_->{$decoded->{'hands'}} . "\n";
   }
}

我希望打印输出是:手指 我的最终结果目标是,“如果 abs 是六块腹肌,则将词手指打印到文件中。”当然,我正在尝试从大型 JSON 大规模地执行此操作。

【问题讨论】:

  • 你能在这里显示$decoded的结果吗
  • use strict; use warnings;
  • 您在内部循环中使用$decoded,但此时您应该只处理$decoded 的子元素。而且它看起来不像“arms”的值是一个哈希,所以你不能写像$...->{'arms'}这样的东西。

标签: perl hash multidimensional-array json


【解决方案1】:

如果你打开了use strictuse 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 中处理复杂结构的更多信息,请参阅以下内容:

阅读它们,再阅读它们,然后编写代码。然后再读一遍。

【讨论】:

    猜你喜欢
    • 2010-12-05
    • 1970-01-01
    • 1970-01-01
    • 2020-02-04
    • 2023-03-08
    • 1970-01-01
    • 2010-12-09
    • 2012-01-02
    • 2016-12-16
    相关资源
    最近更新 更多