Pedro
Pedro

Reputation: 1450

How to loop through a JSON object in Perl?

I'm trying to create an api using perl, the api is for a react native, when the user submits a form on the app I'll get the following object, I'm new to perl and I'm lost trying to loop thro the object :/

{
    checkboxes: [
        {
            id: "1",
            fullname: "Name 1",
            color: "red",
            res: false
        },
        {
            color: "green",
            fullname: "Name 2",
            id: "2",
            res: false
        },
        {
            color: "blue",
            id: "3",
            fullname: "Name 3",
            res: false
        }
    ]
}

my $data_decoded = decode_json($data);

I'm trying this loop, but it only prints the full object.

foreach $a (@data) {
   print "value of a: $a\n";
}

Upvotes: 0

Views: 747

Answers (2)

brian d foy
brian d foy

Reputation: 132802

You turned your JSON into a reference Perl data structure with decode_json (from somewhere, and Mojo::JSON is such a place):

use Mojo::JSON qw(decode_json);
my $data = ...;
my $data_decoded = decode_json($data);

Now you have to figure out how to access whatever you have in $data_decoded. You can look at its structure by dumping it

use Mojo::Util qw(dumper);
print dumper( $data_decoded );

You'll see that the Perl structure is the same as the JSON structure. You have a hash (JSON's Object) that has a checkboxes key that points to an array. The array elements are hashes.

Using Perl v5.24's postfix dereferencing notation, you get all of the array elements:

# uglier circumfix  notation @{$data_decoded->{checkboxes}}
my @elements = $data_decoded->{checkboxes}->@*;

You might put that in a loop:

foreach my $hash ( $data_decoded->{checkboxes}->@* ) {
   ...
   }

Now you get each hash element in $hash and you can do whatever you like with it. That part you haven't told us about yet. :)

The Perl Data Structures Cookbook (perldsc) has a lot of examples of the generation and iteration of various combinations of hash and array references.


You say that you want to do something when the value of the res key is true. In that case, you can use next to skip the items where res is false:

foreach my $hash ( $data_decoded->{checkboxes}->@* ) {
   next unless $hash->{res};
   say "I'm doing something when res is true";
   }

Upvotes: 2

Polar Bear
Polar Bear

Reputation: 6798

Following demo code demonstrates looping through these particular data

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

use JSON;
use Data::Dumper;

my $input = do { local $/; <DATA> };
my $data  = from_json($input);

say Dumper($data);

for my $obj ( @{$data->{checkboxes}} ) {
    say join(",\t", $obj->@{qw/id fullname color/});
}

__DATA__
{
    "checkboxes": [
        {
            "id": "1",
            "fullname": "Name 1",
            "color": "red",
            "res": false
        },
        {
            "color": "green",
            "fullname": "Name 2",
            "id": "2",
            "res": false
        },
        {
            "color": "blue",
            "id": "3",
            "fullname": "Name 3",
            "res": false
        }
    ]
}

Output

$VAR1 = {
          'checkboxes' => [
                            {
                              'res' => bless( do{\(my $o = 0)}, 'JSON::PP::Boolean' ),
                              'color' => 'red',
                              'fullname' => 'Name 1',
                              'id' => '1'
                            },
                            {
                              'fullname' => 'Name 2',
                              'color' => 'green',
                              'res' => $VAR1->{'checkboxes'}[0]{'res'},
                              'id' => '2'
                            },
                            {
                              'id' => '3',
                              'color' => 'blue',
                              'res' => $VAR1->{'checkboxes'}[0]{'res'},
                              'fullname' => 'Name 3'
                            }
                          ]
        };

1,      Name 1, red
2,      Name 2, green
3,      Name 3, blue

Upvotes: 1

Related Questions