http://www.perlmonks.org?node_id=759447


in reply to Re: How do I completely remove an element from an array?
in thread How do I completely remove an element from an array?

There is still the issue of fun things that happen when you edit an array that is used in the controlling loop (as others also pointed out above), so the grep solution gets fun with something like the following not working as one might think:

foreach my $item ( (@array1, @array2) ) { if ( $item =~ /$pattern/i ) { @array1 = grep { $_ != $item } @array1; } }

A solution I'll use to avoid all of the hard thinking is to just create a list of items to remove in the loop, and then as a separate operation delete them all:

my @toRemove; foreach my $item ( (@array1, @array2) ) { if ( $item =~ /$pattern/i ) { push(@toRemove, $item); } } foreach my $item ( @toRemove ) { @array1 = grep { $_ ne $item } @array1; }

Replies are listed 'Best First'.
Re^2: Answer: How do I completely remove an element from an array?
by doug (Pilgrim) on Apr 23, 2009 at 17:25 UTC
    my @toRemove; foreach my $item ( (@array1, @array2) ) { if ( $item =~ /$pattern/i ) { push(@toRemove, $item); } } foreach my $item ( @toRemove ) { @array1 = grep { $_ ne $item } @array1; }

    This is ugly, but to make this approach work, use a hash and remove a loop with a grep.

    my @toRemove = grep m/$pattern/i, @array1, @array2; my %toRemove = map { ($_ => 1) } @toRemove; @array1 = grep ! $toRemove{$_}, @array1;
    and if you like one liners, or simplicity, that becomes
    @array1 = grep ! m/$pattern/i, @array1;
    BTW: What is @array2 doing? It is useless unless you include it in the final line too.

    Now to your issue of fun things that happen when you edit an array that is used in the controlling loop: Yes, that can mess things up. That is part of the reason that you're better off avoiding loops when you're getting rid of data. List operators, like grep and map eliminate a lot of the need for explicit loops.

    Assigning a value to @array1 won't force change its scope. That will do the equivalent of empty all items from the list, and then push the new ones on to the end. No new variables will be created or destroyed.

    If you really like managing loops and arrays yourself, use for instead of foreach, keep an index, and use splice to remove stuff.

    splice @array,7,1;
    will remove the 7th element (remember to count from 0) from the array.

    Hope this helps

    -- doug
Re^2: Answer: How do I completely remove an element from an array?
by gone2015 (Deacon) on Apr 23, 2009 at 10:33 UTC

    Would it not be easier to undef the items to be removed, and then drop them from the array later ?