1

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

2
  • 6
    There is no JSON in your question. Those are Perl data structures. They can be converted to JSON, but your question as it stands has nothing to do with JSON. From your title, I was expecting some obscure regex magic that would avoid full parsing. I'm glad it's not. Commented Jan 17, 2018 at 15:22
  • 1
    Hehe. In my original code I decoded a json string and was parsing it. So I was hung up on that, and put the json tag here. But you are right, this example does not. Commented Jan 18, 2018 at 7:10

4 Answers 4

2

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

my $petibar = { PetiBar => $grades->{PetiBar} };
Sign up to request clarification or add additional context in comments.

Comments

1

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

Comments

1

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.

Comments

1

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

1 Comment

Nice, this will come in handy.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.