tags:

views:

91

answers:

3

I'm trying to parse a JSON string into an array reference:

my $str = '[[2],[1]]';
my $data = map { $_->[0] } @{decode_json( $str )};

but this makes it a scalar. I can do:

my $str = '[[2],[1]]';
my @data = map { $_->[0] } @{decode_json( $str )};
my $data = \@data;

but it's not as short as I like. any help?

+2  A: 

Using an intermediate variable:

my $str = '[[2],[1]]';
my @data = map { $_->[0] } @{decode_json( $str )};
my $data = \@data;
Timmy
+11  A: 

How about:

my $str = '[[2],[1]]';
my $data = [map {$_->[0]} @{decode_json($str)}];
Chris Jester-Young
In general, you can use anonymous array/hash reference constructors whenever you want to have references of an array/hash. e.g., my ($scalarref, $arrayref, $hashref) = (\'foo', ['foo', 'bar'], {foo => 'bar'});
Chris Jester-Young
does that create a temporary array (overhead)?
Timmy
This is something you will have to measure yourself, however, I wrote a test case using Benchmark.pm (and using "map {$_ + 1} 1..1000000"), and my approach is about 25% faster than yours. :-) So, does it have overhead? Who knows. But it certainly has less overhead than the other approach.
Chris Jester-Young
I added my profiling script here: http://stackoverflow.com/questions/942437/change-context-of-return-of-map/947019#947019
Chris Jester-Young
+1  A: 

Since the OP asked which approach has more overhead, here's a quick profile I used to compare the two. Feel free to edit the entry with ways to improve the measurement:

#!/usr/bin/perl -w
use strict;
use Benchmark qw(cmpthese);

sub count(\$$) {
    ${$_[0]} += @{$_[1]};
}

sub a() {
    count($a, [map {$_ + 1} 1..1000000]);
}

sub b() {
    my @d = map {$_ + 1} 1..1000000;
    count($b, \@d);
}

cmpthese(-10, {a => \&a, b => \&b});
Chris Jester-Young