使用perl打印JSON对象

时间:2020-02-14 16:10:57

标签: perl

我是perl的新手,我在下面的代码段中编写了从数据中获取JSON对象的代码。但是输入数据既具有散列又具有数组,那么我如何获得作为数组的“ id”的那些值?

  use strict;
  use warnings;
  use Data::Dumper;
  use JSON

 my $data = '{"total":325,"id": [78,234,737,1253,1459,1733,2166,2653,2855,3133,3414,3538,3729,3905,3991,4110,4160,4536,4692,4701]}';

 print Dumper($data);
 my @hash_ref = from_json($data);

 foreach my $hash_scalar (@hash_ref) {

    foreach (keys %{$hash_scalar}) {
        print "$_ => ${$hash_scalar}{$_}\n";
        }
    }

输出获取

$VAR1 = '{"total":325,"id": 
[78,234,737,1253,1459,1733,2166,2653,2855,3133,3414,3538,3729,3905,3991,4110,4160,4536,4692,4701]}';
id => ARRAY(0x2afee4c)
total => 325

3 个答案:

答案 0 :(得分:2)

id是您获得的哈希引用中的键,并且您想获取其值(它是数组引用)。您可以将其保留为参考,也可以立即获取其元素:

#!perl
use v5.24;
use JSON qw(from_json);

my $data = '{"total":325,"id": [78,234,737]}';

my $json = from_json($data);

# get the hash key to get the hash value, which is an array reference
my $ids_array_ref = $json->{id};

# OR, use the postfix dereference to get the ids as a normal list
my @ids_array = $json->{id}->@*;

# OR, use the older circumfix notation (before Perl v5.24). These are all
# the same:
my @ids_array = @{ $json->{id} };
my @ids_array = @{ $ids_array_ref };
my @ids_array = @$ids_array_ref;

例如:

#!perl
use v5.24;
use JSON qw(from_json);

my $data = '{"total":325,"id": [78,234,737]}';

my $json = from_json($data);

foreach my $id ( $json->{id}->@* ) {
    say "Got id $id";
    }

这将输出:

Got id 78
Got id 234
Got id 737

但是,您也必须处理其他哈希值类型。要决定如何打印某些东西,您必须检查它是否是参考,以及它是哪种参考(我在这里忽略了其他参考):

#!perl
use v5.24;
use JSON qw(from_json);

my $data = '{"total":325,"id": [78,234,737]}';

my $json = from_json($data);

foreach my $key ( keys $json->%* ) {
    print "$key: ";
    if( ref $json->{$key} eq 'ARRAY' ) {
        say join ' ', $json->{$key}->@*;
        }
    elsif( ref $json->{$key} ) { # all other reference types
        warn "I don't handle this yet"
        }
    else {
        say $json->{$key};
        }
    }

但是,您可能具有更深层次的嵌套,因此如果要输出所有内容,则也需要考虑一下。如果我知道我想要什么键,我就不会尝试以一般方式进行所有操作。我直接去想要我想要的东西:

#!perl
use v5.24;
use JSON qw(from_json);

my $data = '{"total":325,"id": [78,234,737]}';

my $json = from_json($data);

say "id: ", join ' ', $json->{id}->@*;
say "total: ", $json->{total};

您的原始代码非常复杂。 from_json的结果是表示JSON数据结构的引用。这是一个JSON对象,Perl称之为哈希,因此您可以得到哈希引用。

my $hash_ref = from_json( $data );

您的示例几乎奏效,因为您获得了一个包含一个元素的数组,该元素是该哈希引用。然后另一个foreach遍历该元素。摆脱该外部数组,摆脱外部循环。

我们介绍了Intermediate Perl中的引用和数据结构,尽管perldsc也很好。我们有一个很深的例子,介绍了深度嵌套和递归的数据结构。

如果您是新手,则可能要从Learning Perl开始。

答案 1 :(得分:0)

我的Perl越来越生锈,但是我认为类似的事情应该可以解决。您需要使用另一个@{...}之类的@{${$hash_scalar}{$_}}取消引用数组引用。

use strict;
use warnings;
use Data::Dumper;
use JSON

my $data = '{"total":325,"id": [78,234,737,1253,1459,1733,2166,2653,2855,3133,3414,3538,3729,3905,3991,4110,4160,4536,4692,4701]}';

print Dumper($data);
my @hash_ref = from_json($data);

for my $hash_scalar (@hash_ref) {
    for my $key (keys(%{$hash_scalar})) {
        print("$key => @{${$hash_scalar}{$_}}\n");
    }
}

答案 2 :(得分:-1)

也许下面的代码将更全面地解决您的问题。

注意:我在数据块中添加了一个哈希作为奖励

use strict;
use warnings;
use feature 'say';

use JSON;
use Data::Dumper;

my $debug = 0;

my $data = '{ "total":325,
              "id": [78,234,737,1253,1459,1733,2166,2653,2855,3133,3414,3538,3729,3905,3991,4110,4160,4536,4692,4701],
              "person": {
                "first": "John",
                "last": "Smith", 
                "age": 27, 
                "occupation": "accountant",
                "wife": "Maria Smith",
                "son": "Alex Smith",
                "daughter": "Samantha Smith",
                "dog": "Sparky",
                "hobby": "photography"
               }
            }';

say Dumper($data) if $debug;

my $json = from_json($data);

say Dumper($json) if $debug;

while( my($k,$v) = each %{$json} ) {
    say "Key: $k";
    if( ref $v eq 'ARRAY' ) {
        say "\tValue is ARRAY";
        for ( @{$v} ) { say "\t\t[$_]" }
    } elsif( ref $v eq 'HASH' ) {
        say "\tValue is HASH";
        while( my($hk,$hv) = each %{$v} ) {
            say "\t\t$hk => $hv";
        }
    } else {
        say "\tValue: $v";
    }
}

say '-' x 40;
say 'Element with index 5 is ' . $json->{id}[5];
say 'Name of the son      is ' . $json->{person}{son};
say 'Name of the daughter is ' . $json->{person}{daughter};

输出

Key: person
        Value is HASH
                son => Alex Smith
                occupation => accountant
                daughter => Samantha Smith
                age => 27
                wife => Maria Smith
                dog => Sparky
                last => Smith
                first => John
                hobby => photography
Key: id
        Value is ARRAY
                [78]
                [234]
                [737]
                [1253]
                [1459]
                [1733]
                [2166]
                [2653]
                [2855]
                [3133]
                [3414]
                [3538]
                [3729]
                [3905]
                [3991]
                [4110]
                [4160]
                [4536]
                [4692]
                [4701]
Key: total
        Value: 325
----------------------------------------
Element with index 5 is 1733
Name of the son      is Alex Smith
Name of the daughter is Samantha Smith
相关问题