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
After giving this some thought my primary suggestion would be to take advantage of perl hashes and do something like the following
-InjunJoel
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.
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.
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
|
---|
In Section
Seekers of Perl Wisdom