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