0
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";
   }
}

印刷結果は次のようになると予想しています: 指 私の最終的な結果の目標は、「腹筋がシックスパックの場合、指という単語をファイルに印刷する」ことです。もちろん、大規模なJSONから大規模にこれを実行しようとしています。

4

1 に答える 1

1

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 のハッシュ要素での初期化されていない値の使用。

21 行目は次のとおりです。

my @layer2 = $_->{$decoded->{'arms'} };

このループで$_は、外側の配列 ( @{ $decoded->{body} }) の各要素に が設定されます。その配列の各要素はハッシュ参照です。あなたがしているのは、ハッシュarms最初のレベルのキーを、配列内の要素が指すハッシュへのキーとして使用しようとしていることです。そのキーはこれらのハッシュには存在しないため、初期化されていない値に関する警告が表示されます。

欲しいものを手に入れるために必要なのは

my @layer2 = @{ $_->{arms} };

3 番目の層はより複雑です。ハッシュの配列ではなく、コロンで区切られた文字列の配列です。そのループでは、必要のない文字列を見つけるまで捨てることができます。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 での複雑な構造の操作の詳細については、次を参照してください。

それらを読んで、もう一度読んでから、コードを書きます。それからそれらをもう一度読んでください。

于 2013-09-12T06:15:38.187 に答える