Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Hello Monks!
I need to remove one level from this array, can't think how to get it done.
In a nut shell, the original data comes as an example like this:
$VAR1 = [ [ {},... ],[ {},... ]...];
I need it to be as this:
$VAR1 = [ {},... ],[ {},... ]...;

Here is the code that shows how I am trying.
#!/usr/bin/perl use strict; use warnings; use Data::Dumper; my $recs = collect(); print Dumper $rec; =code $VAR1 = [ [ { 'YEAR' => '2008', 'MONTH' => 'MARCH', 'COLOR_CODE' => '1' }, { 'YEAR' => '2014', 'MONTH' => 'APRIL', 'COLOR_CODE' => '2' }, { 'YEAR' => '2014', 'MONTH' => 'DECEMBER', 'COLOR_CODE' => '3' } ], [ { 'YEAR' => '2001', 'MONTH' => 'MAY', 'COLOR_CODE' => '1' }, { 'YEAR' => '2009', 'MONTH' => 'JUNE', 'COLOR_CODE' => '2' }, { 'YEAR' => '2001', 'MONTH' => 'MAY', 'COLOR_CODE' => '1' }, { 'YEAR' => '2009', 'MONTH' => 'JUNE', 'COLOR_CODE' => '2' }, { 'YEAR' => '2013', 'MONTH' => 'JULY', 'COLOR_CODE' => '2' }, { 'YEAR' => '2016', 'MONTH' => 'SEPTEMBER', 'COLOR_CODE' => '4' } ] ]; =cut my @test = (); foreach my $rec ( @{$recs} ) { warn Dumper $rec; # This prints the data structure I am looking for +: =code $VAR1 = [ { 'YEAR' => '2008', 'MONTH' => 'MARCH', 'COLOR_CODE' => '1' }, { 'YEAR' => '2014', 'MONTH' => 'APRIL', 'COLOR_CODE' => '2' }, { 'YEAR' => '2014', 'MONTH' => 'DECEMBER', 'COLOR_CODE' => '3' } ]; $VAR1 = [ { 'YEAR' => '2001', 'MONTH' => 'MAY', 'COLOR_CODE' => '1' }, { 'YEAR' => '2009', 'MONTH' => 'JUNE', 'COLOR_CODE' => '2' }, { 'YEAR' => '2001', 'MONTH' => 'MAY', 'COLOR_CODE' => '1' }, { 'YEAR' => '2009', 'MONTH' => 'JUNE', 'COLOR_CODE' => '2' }, { 'YEAR' => '2013', 'MONTH' => 'JULY', 'COLOR_CODE' => '2' }, { 'YEAR' => '2016', 'MONTH' => 'SEPTEMBER', 'COLOR_CODE' => '4' } ]; =cut push @test, $rec; # The print Dumper will get the data structure b +ack to its original format # I need it in the structure of the $rec Dumper above. } print Dumper \@test; # This is what I am trying to get: =code $VAR1 = [ { 'YEAR' => '2008', 'MONTH' => 'MARCH', 'COLOR_CODE' => '1' }, ... ]; $VAR1 = [ { 'YEAR' => '2001', 'MONTH' => 'MAY', 'COLOR_CODE' => '1' }, ... ]; =cut sub collect { ... # <<< data in $more_rec; my @all = (); foreach my $number ( keys %{$more_rec} ) { my $numbers = $more_rec->{$numbers}; push @all, $numbers->{agenda}; } return \@all }
Thanks for looking!

Replies are listed 'Best First'.
Re: Remove one level from array
by LanX (Saint) on Oct 28, 2015 at 15:39 UTC
     $a_new = $a_old->[0] ?

    UPDATE

    I'm confused, cause this doesn't really make sense

    > $VAR1 = [ {},... ],[ {},... ]...;

    might be you want:

    @new = @$a_old;

    if not please explain.

    Cheers Rolf
    (addicted to the Perl Programming Language and ☆☆☆☆ :)
    Je suis Charlie!

      That was just to illustrate the data structure, the code sample shows it better.
Re: Remove one level from array
by stevieb (Canon) on Oct 28, 2015 at 15:54 UTC

    What you have is an array of arrays of hashes. You can not strip off the outer array, or else you'd be trying to stuff a bunch of array refs into a single scalar, and that won't fly.

    What I think you want to do is simply iterate over the encompassing array and act on each inner aref one at a time:

    my @numbers = collect(@test); sub collect { my @test = @_; my @all; for my $more_rec (@test){ for my $number (keys %{ $more_rec }){ my $numbers = $more_rec->{$number}; push @all, $numbers->{agenda}; } } return @all; }

    However, it's doubly difficult to really understand what you want, because your data examples do not jive with what was in your collect() function. In there, you're extracting an href ($numbers) from within another href ($more_rec), and then from within $numbers, you're extracting the value of the agenda key. None of that is shown in your example data. Also, your collect() has at least one issue. You extract $number from keys(), but then never proceed to use it.

Re: Remove one level from array
by hdb (Monsignor) on Oct 28, 2015 at 15:54 UTC

    How about

    $VAR1 = [ map { 'ARRAY' eq ref( $_ ) ? @$_ : $_ } @$VAR1 ];
Re: Remove one level from array
by poj (Abbot) on Oct 28, 2015 at 16:45 UTC
    Try
    #!/usr/bin/perl use strict; use warnings; use Data::Dumper; my $more_rec = { '1'=>{ 'agenda' => [ {'YEAR'=>'2008','MONTH'=>'MARCH', 'COLOR_CODE'=>'1' }, {'YEAR'=>'2014','MONTH'=>'APRIL', 'COLOR_CODE'=>'2' }, {'YEAR'=>'2014','MONTH'=>'DECEMBER','COLOR_CODE'=>'3'}, ], }, '2'=>{ 'agenda' => [ {'YEAR'=>'2001','MONTH'=>'MAY', 'COLOR_CODE'=>'1' }, {'YEAR'=>'2009','MONTH'=>'JUNE','COLOR_CODE'=>'2' }, {'YEAR'=>'2001','MONTH'=>'MAY', 'COLOR_CODE'=>'1' }, {'YEAR'=>'2009','MONTH'=>'JUNE','COLOR_CODE'=>'2' }, {'YEAR'=>'2013','MONTH'=>'JULY','COLOR_CODE'=>'2' }, {'YEAR'=>'2016','MONTH'=>'SEPTEMBER', 'COLOR_CODE'=>'4' } ], }, }; my $recs = collect(); print Dumper $recs; sub collect { my @all = (); foreach my $number ( keys %{$more_rec} ) { my $ar = $more_rec->{$number}; for my $mth (@{$ar->{'agenda'}}){ push @all, $mth; } } return \@all; }
    poj
      Got it to work this way:
      ... push @all, @{$numbers->{agenda}}; ...
      Thank you!