Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a perl "not in" operator?

Tags:

perl

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

like image 390
trinity Avatar asked Jan 26 '11 19:01

trinity


2 Answers

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.)

like image 171
Ether Avatar answered Sep 24 '22 03:09

Ether


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;
like image 22
Eric Strom Avatar answered Sep 20 '22 03:09

Eric Strom