I recently ran across a terrible situation in which

$values = an Array of Arrays

included an element I wanted to remove. Here's how I did it.
for $d ($values) { for $x (0..100) { if (!defined(${$d}[$x]) ) { last;} #${$d}[$x] = "" if (${$d}[$x] eq "UNKNOWN"); splice (@$values, $x, 1) if (${$d}[$x] eq "UNKNOWN"); } }
The commented out line would be used if I wanted to simply empty the element that contained "UNKNOWN". The splice function proves it's usefulness here. I looked high and low for an example of splicing a multidimensional array and never found one. I hope this helps someone.

Replies are listed 'Best First'.
Re: Multidimensional arrayrefs constructed from anonymous arrayrefs
by tilly (Archbishop) on May 06, 2004 at 21:44 UTC
    You're missing an @ in front of $values. You're assuming that you know the maximum size of the inner arrays (101 elements each). And your code doesn't run under strict.pm. Something like this (untested) avoids all of these issues:
    foreach my $row (@$values) { @$row = grep {$_ ne "UNKNOWN"} @$row; }
    Though if I'm working with an array of arrays, I don't generally want to just eliminate random elements and let the other ones move around. I generally think of position $i, $j as coordinates that should remain fixed. But YMMV.
Re: Multidimensional arrayrefs constructed from anonymous arrayrefs
by Roy Johnson (Monsignor) on May 06, 2004 at 19:11 UTC
    You left the "@" out of your first line. And you should iterate through the element indices, rather than guessing that there will be 100 or fewer.

    But your splice is removing an element from your top-level array if the corresponding element of an inner array has the forbidden value. I don't think that's sensible. Your commented line suggests you want to remove from the inner array:

    for $d (@$values) { for $x (0..$#$d) { splice(@$d, $x, 1) if $d->[$x] eq 'UNKNOWN'; } }

    The PerlMonk tr/// Advocate
Re: Multidimensional arrayrefs constructed from anonymous arrayrefs
by dragonchild (Archbishop) on May 06, 2004 at 18:06 UTC
    I looked high and low for an example of splicing a multidimensional array and never found one.

    Maybe I'm missing something, but wouldn't the following work?

    use Data::Dumper; my @arr = ( [ 0 .. 2 ], [ 3 .. 5 ], [ 6 .. 8 ], ); print Data::Dumper->Dump( [\@arr] ); splice @{$arr[2]}, 1, 1; print Data::Dumper->Dump( [\@arr] ); -------- $VAR1 = [ [ 0, 1, 2 ], [ 3, 4, 5 ], [ 6, 7, 8 ] ]; $VAR1 = [ [ 0, 1, 2 ], [ 3, 4, 5 ], [ 6, 8 ] ];

    ------
    We are the carpenters and bricklayers of the Information Age.

    Then there are Damian modules.... *sigh* ... that's not about being less-lazy -- that's about being on some really good drugs -- you know, there is no spoon. - flyingmoose

    I shouldn't have to say this, but any code, unless otherwise stated, is untested

Re: Multidimensional arrayrefs constructed from anonymous arrayrefs
by jryan (Vicar) on May 06, 2004 at 18:32 UTC

    It might be easier (and faster asymptotically) to just build a new array in this case:

    my @new; foreach my $array ($values) { my @inner; foreach my $value ($array) { push @inner, $value if $value ne "UNKNOWN" } push @new, \@inner } $values = \@new;

    Or, if you like to be fancy:

    $values = [ grep { $_ = [ grep { $_ ne "UNKNOWN" } @$_ ] } @$values ]