Basically, I have an array, let's say @badvalues
.
I have another array, let's say @values
.
Basically, I want this:
For each element in @badvalues
- See if it is in
@values
- If it is, delete it
- Ultimately, I should end up with either the array
@values
, containing no elements that are in the开发者_JS百科 array@badvalues
, or a new array,@goodvalues
, containing every element of@values
that is not an element of@badvalues
.
I know it sounds simple, and maybe it's because I'm tired, but I can't seem to find a clear answer to this question when searching around.
# Get only bad values
my %values = map {$_=>1} @values;
my @new_badvalues = grep { !$values{$_} } @badvalues;
# Get only good values
my %badvalues = map {$_=>1} @badvalues;
my @goodvalues = grep { !$badvalues{$_} } @values;
# An alternative
@badvalues{@badvalues} = ();
foreach $item (@values) {
push(@goodvalues, $item) unless exists $badvalues{$item};
}
For more complete reference, please see "Chapter 4.7. Finding Elements in One Array but Not Another" of "Perl Cookbook"
If you've got a modern Perl version, like say >= 5.10.1, then you can also do this:
my @final_good = grep { !($_ ~~ @badvalues ) } @values;
or for clearer precendence:
my @final_good = grep { not $_ ~~ @badvalues } @values;
This is using the smartmatch operator that was added in Perl 5.10.
Little bit faster and less memory consuming version of approach shown in DVK's answer
my %badvalues;
@badvalues{@badvalues} = ();
my @goodvalues = grep !exists $badvalues{$_}, @values;
精彩评论