http://www.perlmonks.org?node_id=400532
Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

if I have
\$foobar='D';
@array=('A', 'B', 'C', 'D');

is there a way I can compare \$foobar to every @array value in a single if statement? without a loop?

for example...

```if(\$foobar eq @array[0 to 3]{
}

I dont think that works, but it might help describe what Im saying better... thanks

Replies are listed 'Best First'.
Re: Compare all array values without a loop
by edan (Curate) on Oct 19, 2004 at 14:19 UTC
```if ( grep { \$_ eq \$foobar} @array )
{
}

Update: Use the above code if you really want to compare all array values (which is what you said). If you really want to just know if the value is in the array (and then stop searching), you might try the following, which might perform better in certain situations:

```use List::Util qw(first);
if ( first { \$_ eq \$foobar } @array )
{
}
--
edan

I believe the original poster wanted to know whether every value in the array equalled the given value, not whether it occurred once. Perhaps he could clarify. (Of course, now both answers are available in replies.)
rjbs

I think it's not very clear from the original post, but my assumption was that the poster was looking to solve the "is this value in this list" problem, so that's what I solved. I think this is a far more common problem than "is this list composed exclusively of this value"... don't you?

--
edan

Assuming that \$foobar isn't undefined you should have a definedness check for the return value of first too. \$foobar may be 0 or "".

If undef is allowed as comparision value, use

```    defined(
defined \$foobar
? first { \$_ eq \$foobar } @array
: first { not defined \$array[\$_] } 0 .. \$#array
)

ihb

See perltoc if you don't know which perldoc to read!

Quantum::Superpositions has any() and all() operations that may fit the bill. I don't know how the performance compares to List::Util and don't have time to check. Its just a fun module.
yay, thank you!
Re: Compare all array values without a loop
by dragonchild (Archbishop) on Oct 19, 2004 at 14:25 UTC
```use Quantum::Superpositions;

my \$foobar = 'D';
my @array = 'A' .. 'D';

if (\$foobar eq any( @array ) ) {
print "Yay!\n";
} else {
print "Boo\n";
}

In Perl6, the any and all functions will be keywords.

Being right, does not endow the right to be rude; politeness costs nothing.
Being unknowing, is not the same as being stupid.
Expressing a contrary opinion, whether to the individual or the group, is more often a sign of deeper thought than of cantankerous belligerence.
Do not mistake your goals as the only goals; your opinion as the only opinion; your confidence as correctness. Saying you know better is not the same as explaining you know better.

Re: Compare all array values without a loop
by fergal (Chaplain) on Oct 19, 2004 at 14:28 UTC
If you're basically looking for a quick Set membership test then using a hash rather than an array coould help.
```my %hash = ('a' => undef, 'b' => undef, 'c' => undef, 'd' => undef);

if (exists \$hash{'a'})
{
}
Setting up the hash can be made a bit neater once you know what a hash slice is
```my %hash;
@hash{'a', 'b', 'c', 'd'} = ();
If your set of elements is going to be large and you're going to be checking frequently then a hash will be much quicker than anything that searches an array. Inserting and removing elements is also quick and doesn't have a problem with duplicates like an array could.

You could also do a cpan search for "set" and use one of the modules there, some of them would be even faster and than hashes I think.

Re: Compare all array values without a loop
by rjbs (Pilgrim) on Oct 19, 2004 at 14:22 UTC
```if (grep({ \$_ eq \$foobar } @array) == @array) { ... }
"If the number of elements equal to \$foobar is the same as the number of elements in the array..." or
```unless (grep { \$_ ne \$foobar} @array) { ... }
"Unless you find an element that is not equal to foobar..."

Of course, these are both loops of a kind.
rjbs
Re: Compare all array values without a loop
by radiantmatrix (Parson) on Oct 19, 2004 at 14:35 UTC

You could join the array into a scalar with an unusual character as a separator, then use a match.

```\$foobar='D';
\$sep = chr(1);

@array = ('A','B','C','D');
if ((\$sep.join(\$sep,@array).\$sep) =~ m/\$sep\$foobar\$sep/) {
print "Found a \$foobar in \@array!";
}

The \$sep on either side of the join() ensures that any potential match will begin and end with chr(1). You can pick other separator characters, as long as you can be sure they will not exist in your array (chr(1) is a pretty unlikely thing to find).

Of course, it would be better to use hash-keys if you can...

```\$foobar='D';
%hash = ( 'A' => undef, 'B' => undef, 'C' => undef, 'D' => undef );
print "Found a \$foobar in \%hash" if exists \$hash{\$foobar};

If you're avoiding multiple loop passes for performance, then you could use a one-time loop to convert the array to a hash:

```@array = ('A','B','C','D');
for (@array) {
\$hash{\$_} = undef;
}

#now we have the same hash as in the previous example.
#so, you can do this repeatedly with out a hit:

\$foo = 'D';
if (exists \$hash{\$foo}) {
print "There was a \$foo in the array\n";
}
require General::Disclaimer;
"Users are evil. All users are evil. Do not trust them. Perl specifically offers the -T switch because it knows users are evil." - japhy

```@array = ('A','B','C','D');
for (@array) {
\$hash{\$_} = undef;
}
you can use
```my @array = qw/A B C D/;
my %hash;
@hash{@array} = ();

Re: Compare all array values without a loop
by si_lence (Deacon) on Oct 19, 2004 at 14:25 UTC
Hi,
You can use grep for it.
This uses an implicit loop, but it is quite close to
the syntax you suggest:
```my  \$foobar='D';
my  @array=('A', 'B', 'C', 'D');
if ( grep {\$_ eq \$foobar } @array ) {
};

si_lence
Re: Compare all array values without a loop
by Random_Walk (Prior) on Oct 19, 2004 at 15:54 UTC

Just for fun here is an evil eval way to do it without a loop.

```@a=('A', 'B', 'C', 'D');
\$b='D';
if (eval "if(\\$b eq \"".(join"\"){return 1}if(\\$b eq \"",@a)."\"){retu
+rn 1}") {
Print "It was there\n"
}