in reply to Re: Flatten sparse AoA
in thread Flatten sparse AoA

That does something else then what the OP does. You're filtering out the undefined elements of @$aoa (that is, top level elements), while the OP wants to remove (according to his code), the undefined elements of the elements of @$aoa.

That is, if $aoa is

[ [2, undef, 4], [undef, undef, 5], ];
he wants to end with
(2, 4, 5)
not with
(2, undef, 4, undef, undef, 5)
which is what your code ends up with.

Note that you probably intended to write defined $_ instead of defined @$_.

Replies are listed 'Best First'.
Re^3: Flatten sparse AoA
by Marshall (Canon) on Jan 22, 2012 at 19:35 UTC
    Yes, thank you.

    Update:

    #!/usr/bin/perl -w use strict; use Data::Dumper; $|++; my @AoA = ( undef, [1, 2], undef, [3, 4]); my @flat = map{defined (@$_) ? @$_ : ()}@AoA; print join (",",@flat),"\n"; # prints: 1,2,3,4 my $AoAref = \@AoA; @flat = map{ defined (@$_) ? @$_ : () }@$AoAref; print join (",",@flat),"\n"; # prints: 1,2,3,4 =so far prints:... 1,2,3,4 1,2,3,4 =cut @AoA = ( undef, [1, undef], undef, [3, 4]); $AoAref = \@AoA; # "undef" is a legal Perl value. # to handle this idea of an undef value within # an defined array (undef is a legal Perl value)! Yes, use grep. # # my map filters out "undefined references to arrays" # within an AoA, I would use grep to filter # that undesired "undef" value out if what is meant # a value within in an array. # as shown before: grep{} map{}.
    My code is just a special case.
    The more general case is to flatten the whole thing out and grep out the undefined values provided that if what is meant by "sparse" is that not only entire rows are missing but also columns within defined rows. "undef" is a legal Perl value and requires some kind of "grep" to "get rid of it"
      My code is just a special case.
      A very, very special case. In your defined (@$_), you are trying to derefence $_ unconditionally. Considering you are using strict, this only succeeds in three cases: if $_ is an array reference, if $_ is an object with overloaded array dereferencing, or if $_ in undefined (but not in the general case, it seems only defined @$var, with $var undefined is allowed. @$var isn't, nor is defined @{+undef}). It's a run time to try to dereference a defined non-reference, or a reference that isn't an array (and doesn't have array reference overloading).

      Why not just:

      @flat = map {$_ ? @$_ : ()} @AoA;
      if you're assuming @AoA has arrayrefs and undefined values, and nothing else.