Orjanp
Orjanp

Reputation: 10951

Perl, iterate through a json string, get key/value object in one variable

Have been looking for a way to get both the key\value from a json string without having to build a new json string based on the pair.

Having the following example code: (I have modified code from Here)

#!/usr/bin/perl
use strict;
use warnings;

use Data::Dumper qw(Dumper);

my $grades = {'PetiBar' => {
                          'Mathematics' => 82,
                          'Art' => 99,
                          'Literature' => 88
                        },
          'FooBar' => {
                         'Mathematics' => 97,
                         'Literature' => 67
                       }
        };

The result I'm looking after is:

'PetiBar' => {
             'Mathematics' => 82,
             'Art' => 99,
             'Literature' => 88
             }

This will give both objects, not only one:

foreach my $val ($grades) {
    print Dumper $val;
}

This will only give me the values without the key:

foreach my $key (keys %{$grades}) {
    print Dumper $grades->{$key};
}

How do I get both in a variable? Do I have to take the key and value, and build a new json string from them?

I have some running code here

Upvotes: 1

Views: 1995

Answers (4)

jreisinger
jreisinger

Reputation: 1643

You can set Data::Dumper's configuration variable $Data::Dumper::Varname to the value of the key:

foreach my $key ( keys %$grades ) {
    $Data::Dumper::Varname = $key;
    ## remove '#' to enable the if clause
    print Dumper $grades->{$key} # if $key eq "PetiBar";
}

This will result in the following output:

$FooBar1 = {
             'Mathematics' => 97,
             'Literature' => 67
           };
$PetiBar1 = {
              'Mathematics' => 82,
              'Literature' => 88,
              'Art' => 99
            };

Upvotes: 1

atomicstack
atomicstack

Reputation: 819

There are many ways to do what you want, here's one way:

my %slice = map { $_ => $grades->{$_} } qw/Petibar/

The qw// list at the end means you can easily add more keys to extract from the same structure, if needed.

Upvotes: 1

tinita
tinita

Reputation: 4346

The following does exactly what you asked for, but see the other answers if you need something more flexible:

my $petibar = { PetiBar => $grades->{PetiBar} };

Upvotes: 2

simbabque
simbabque

Reputation: 54381

If your Perl is at least version 5.20, you can use a hash slice for this.

my %foo = qw/a 1 c 2 e 3/;
my %bar = %foo{qw/a c/};

Yes, that's right, there is a % sigil in front of the {}. There can be a list inside the curly braces.

This is what %bar will contain.

(
    a =>  1,
    c =>  2
)

Typically that would be done with a hash, but since you've got a hash reference, you need to dereference, and then create a new anonymous reference that the key/value pair(s) go into.

my $slice = { %{$grades}{PetiBar} };

Upvotes: 1

Related Questions