Suppose I have an array of numbers and I want to ensure that all of these fall within one of the set (x,y,z), I'm currently checking that the following evaluates to 0 :
scalar ( grep { $_ ne x && $_ ne y && $_ ne z } @arr )
Was just wondering if it'll not be easier if we had "IN" and "NOT IN" sql-like operators in perl too..
scalar ( grep { $_ NOT IN (x,y,z) } @arr )
Or is there one already ??
Thanks, Trinity
The libraries List::Util or List::MoreUtils are very useful here for testing list membership where you don't care about the values itself, but simply existence. These are more efficient than grep, because they stop looping through the list as soon as a match is found, which can really speed things up with long lists. Moreover these modules are written in C/XS, which is faster than any pure-perl implementation.
use List::MoreUtils 'any';
my @list = qw(foo bar baz);
my $exists = any { $_ eq 'foo' } @list;
print 'foo ', ($exists ? 'is' : 'is not'), " a member of the list\n";
$exists = any { $_ eq 'blah' } @list;
print 'blah ', ($exists ? 'is' : 'is not'), " a member of the list\n";
(If you are restricted to only using modules that come with core Perl, you can use first in List::Util -- it first shipped with perl in 5.7.3.)
A typical way to solve this is to use a hash:
my %set = map {$_ => 1} qw( x y z ); # add x, y and z to the hash as keys
# each with a value of 1
my @not_in_set = grep {not $set{$_}} @arr;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With