печать JSON объектов с использованием perl - PullRequest
1 голос
/ 14 февраля 2020

Я новичок в 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";
        }
    }

Output Getting

#
$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 ]

2 голосов
/ 14 февраля 2020

id - это ключ в ссылке ha sh, которую вы возвращаете, и вы хотите получить ее значение, которое является ссылкой на массив. Вы можете сохранить это в качестве ссылки или сразу получить его элементы:

#!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

Но, Вы должны обрабатывать и другие типы значений ha sh. Чтобы решить, как печатать что-то, вы должны проверить, является ли это ссылкой и какой это тип ссылки (я игнорирую другие виды здесь):

#!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};
        }
    }

Но, вы можете иметь более глубокие уровни вложения, так что вам тоже нужно подумать об этом, если вы хотите вывести все. Если я знаю, какие ключи мне нужны, я не буду пытаться go пройти через все в общем. Я go хочу напрямую Я хочу:

#!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 называет ха sh, поэтому вы получаете ссылку ha sh.

my $hash_ref = from_json( $data );

Ваш пример почти сработал, потому что вы получили массив один элемент, который является ссылкой ha sh. Другой foreach затем перебирает этот один элемент. Избавьтесь от этого внешнего массива, и вы избавитесь от внешнего l oop.

Мы покрываем ссылки и структуры данных в Intermediate Perl, хотя perlds c тоже хорошо. У нас есть длинные примеры глубоко вложенных и рекурсивных структур данных.

Если вы новичок, вы можете начать с Learning Perl, хотя.

0 голосов
/ 14 февраля 2020

Возможно, следующий код охватит ваш вопрос в более полной степени.

ПРИМЕЧАНИЕ: Я добавил ха sh в блок данных в качестве бонуса

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
0 голосов
/ 14 февраля 2020

Мой 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");
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...