Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl: the Markov chain saw
 
PerlMonks  

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

by Anonymous Monk
on Sep 05, 2015 at 15:57 UTC ( [id://1141155]=note: print w/replies, xml ) Need Help??


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

So how would you take the next step and represent this data in perl. For instance, if at the end of all this I want @name to hold 'Theodor Nelson','Morton Heilig' ,and @id to hold '_333301','_13204' how would I do that? I tried my @names = @{ $inventors_array[1]->{"name"}    }; but that gives me
Can't use string ("Morton Heilig") as an ARRAY ref while "strict refs" + in use
I'm not trying to define $names[Morton Heilig] = something, I'm trying to define $names[1]=Morton Heiling, or alternatively $names{_13204} = 'Morton Heilig'

Replies are listed 'Best First'.
Re^3: JSON and Perl Objects - How to access data?
by 1nickt (Canon) on Sep 05, 2015 at 17:40 UTC

    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.

      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:  <%-{-{-{-<

      Really good ! small typo error... my $id = $item->{'id'}; # in line 37 instead of name, it should be id
Re^3: JSON and Perl Objects - How to access data?
by poj (Abbot) on Sep 05, 2015 at 16:39 UTC
    Use map
    my @names = map { $_->{name} } @inventors_array ; my @id = map { $_->{id} } @inventors_array ; my %names = map { $_->{id}, $_->{name} } @inventors_array;
    poj

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://1141155]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others surveying the Monastery: (None)
    As of 2024-04-25 01:43 GMT
    Sections?
    Information?
    Find Nodes?
    Leftovers?
      Voting Booth?

      No recent polls found