http://qs321.pair.com?node_id=1141159


in reply to Re^2: JSON and Perl Objects - How to access data?
in thread JSON and Perl Objects - How to access data?

Good job searching to find this old thread! Your question is not related to JSON, but rather to perl data structures. See perlref.

You should get in the habit of using Data::Dumper to examine your complex data structures. In this case, you still were unclear on how to access the nested data, but examining the structure is always the first step.

(Note that jsonToObject in the OP is deprecated.)

Here's an example that shows how to get your arrays. It's commented so you can see what's going on, and it deliberately uses more steps than optimal to be clear (if you really wanted to build separate arrays, you should probably use map).

#!/usr/bin/perl use strict; use warnings; use feature qw/ say /; use Data::Dumper; use JSON; my $data = qq# { "items" : [ { "name" : "Theodor Nelson", "id": "_333301" }, { "name": "Morton Heilig", "id": "_13204" } ] } #; my $obj = from_json( $data ); my @names; my @ids; say Dumper $obj; # $obj is an anonymous hash with one key, 'items' my @items = @{ $obj->{'items'} }; # The value of the key 'items' is an anonymous array. # Here for simplicity we copy it into a new array. # We access it by deferencing it using @{ } foreach my $item ( @items ) { # Each element of the anonymous array is a hashref. # So $item is a hashref, not a scalar my $name = $item->{'name'}; my $id = $item->{'name'}; push @names, $name; push @ids, $id; } say 'Names: ' . join ', ', @names; say 'IDs: ' . join ', ', @ids; __END__
A more idiomatic way to put the data into a hash keyed by ID as you suggested above:
#!/usr/bin/perl use strict; use warnings; use feature qw/ say /; use Data::Dumper; use JSON; my $data = qq# { "items" : [ { "name" : "Theodor Nelson", "id": "_333301" }, { "name": "Morton Heilig", "id": "_13204" } ] } #; my $obj = from_json( $data ); my %names; $names{ $_->{'id'} } = $_->{'name'} for @{ $obj->{'items'} }; while ( my( $id, $name ) = each %names ) { say "$id: $name"; } __END__
Output:
$ perl 651544-2.pl _13204: Morton Heilig _333301: Theodor Nelson $
And finally, how to access the names directly in the object:
#!/usr/bin/perl use strict; use warnings; use feature qw/ say /; use Data::Dumper; use JSON; my $data = qq# { "items" : [ { "name" : "Theodor Nelson", "id": "_333301" }, { "name": "Morton Heilig", "id": "_13204" } ] } #; my $obj = from_json( $data ); say ${ $obj->{'items'}->[1] }{'name'}; # ^ ^ ^ ^ ^ ^ # | | | | | | # | is an arrayref | ----------- # | | | # | first element of which is a hash | # | | # the variable is value of the 'name' key __END__
Hope this helps!

The way forward always starts with a minimal test.

Replies are listed 'Best First'.
Re^4: JSON and Perl Objects - How to access data?
by Anonymous Monk on Sep 06, 2015 at 04:35 UTC

    Wow- that is awesome. Thank you for the well commented answer. I really appreciate it.

    I'm going to have to wrap my head around

    say ${ $obj->{'items'}->[1] }{'name'};

    but other than that I'm there. Thanks again!

      See also the Data Structures Cookbook.

      I'm going to have to wrap my head around ...

      One way to go about that is to dump (see Data::Dumper; see also Data::Dump) the Perl object reference in stages, and from the inside out (i.e., top level to bottom):
          print Dumper $obj->{'items'};
      will show that you have a reference to an array. Then
          print Dumper $obj->{'items'}->[1];
      will show that one element of the array contains a hash reference. Finally,
          print Dumper ${ $obj->{'items'}->[1] }{'name'};
      will show the value of one key of the referent.

      Update: BTW: the expression
          ${ $obj->{'items'}->[1] }{'name'}
      is equivalent to the more concise and IMHO preferable
          $obj->{'items'}[1]{'name'}


      Give a man a fish:  <%-{-{-{-<

Re^4: JSON and Perl Objects - How to access data?
by Anonymous Monk on May 25, 2018 at 00:37 UTC
    Really good ! small typo error... my $id = $item->{'id'}; # in line 37 instead of name, it should be id