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


in reply to Removing array elements

Greetings all,
Seeing as from your post you are open to learning some of the Perl specific syntactic magic that exists
I was told that I shouldn't use the C format of using for (i.e. for ($i=0;$i<10;$i++) for replacing the array's elements but use perl's for/foreach command. That works fine...

After giving this some thought my primary suggestion would be to take advantage of perl hashes and do something like the following
use strict; my @a = (1..20); my @b = (2,3,13,14,17); @a = do{my %i; undef @i{@a}; delete @i{@b}; sort {$a<=>$b} keys %i};

Another suggestion would be to get familiar with map which is a succinct way of writing a foreach. What map allows you to do is iterate over a list, be it an array, the keys of a hash, a range of numbers, letters, etc. and manipulate the contents element by element with a block of logic in a closure. In combination with grep map comes in very handy for just this sort of thing.
use strict; #Lets say we have two arrays @a and @b #and we want to, as in your posting, remove the elements in @b #from those in @a my @a = (1..20); my @b = (5,8,13,16); #we in essence re-write the contents of @a with our map statement #that allows us to check the values for those we want to remove. @a = map{ my $i = $_; (grep /^$i$/, @b) ? () : $i ; }@a;

The above code feeds in the existing elements of @a one at a time assigning each value to $_ within the closure/block {}, it then assigns this value to the locally scoped variable $i for reasons that will make sense in a second. grep is used to check for the value in our @b array, however since grep can also have a closure and it also assigns its values to $_ we check against $i (told you it would make sense). The logic for the check is contained in a ternary (if)?true:false; construct that returns either an empty list (), in effect nothing, or the value of $i if not found in @b, all of which gets fed into the new version of @a. The regexp anchors ^ and $ are used to keep partial matches from messing with things, like '2' matching against '12,20...29,32,42,52,etc'.
Seems like I have written this before... maybe because I have.


-InjunJoel
"I do not feel obliged to believe that the same God who endowed us with sense, reason and intellect has intended us to forego their use." -Galileo