go ahead... be a heretic PerlMonks

### How to Do Multiple OR in For Loops

by neversaint (Deacon)
 on Apr 13, 2011 at 01:30 UTC Need Help??
neversaint has asked for the wisdom of the Perl Monks concerning the following question:

Dear Masters,
I have a hard-coded if loops that looks like this:
```    my \$tp = 0;
my \$fp = 0;
if (   \$myhash{\$pred}
|| \$myhash{\$pred1}
|| \$myhash{\$pred2}
|| \$myhash{\$pred3}
|| \$myhash{\$pred4}
|| \$myhash{\$pred5}
|| \$myhash{\$pred6} )
{
\$tp++;
}
else {
\$fp++;
}
How can I do that in for loops? I tried the following but it give different result:
```my \$tp=0;
my \$fp=0;

my @allpreds = (\$pred,\$pred1,\$pred2,\$pred3,\$pred4,\$pred5);

foreach my \$allpred ( @allpreds ) {
if ( \$myhash{\$allpred} ) {
\$tp++;

}

}
if ( !myhash{\$pred} ) {
\$fp++;
}

---
neversaint and everlastingly indebted.......

Replies are listed 'Best First'.
Re: How to Do Multiple OR in For Loops
by davido (Archbishop) on Apr 13, 2011 at 01:44 UTC

Try this:

```my \$tp = 0;
my \$fp = 0;
for( \$pred, \$pred1, \$pred2, \$pred3, \$pred4, \$pred5, \$pred6 ) {
if( \$myhash{\$_} ) {
\$tp++;
} else {
\$fp++;
}
}

You might consider avoiding all those variable names with numbers. Just drop the values into an array called @pred in the first place. Then it would look like:

```for( @pred ) {
.........

Dave

Re: How to Do Multiple OR in For Loops
by ikegami (Pope) on Apr 13, 2011 at 01:54 UTC
I'd go for
```my \$tp = grep { \$myhash{ \$_ } } @pred;

If the boolean needs to be formatted into '0' and '1' for output, that's the output code's job, and it can be done there trivially using « ? '1' : '0' ».

Using "for", it would look like

```my \$tp = 0;
for ( @pred ) {
if ( \$myhash{ \$_ } ) {
\$tp = 1;
last;
}
}
or
```my \$tp = 0;
for ( @pred ) {
last if \$tp = \$myhash{ \$_ };
}
Re: How to Do Multiple OR in For Loops
by LanX (Bishop) on Apr 13, 2011 at 02:16 UTC
List::Util is core, try importing reduce();

untested:  if ( reduce { \$a||\$b } @myhash{@allpreds} ) {...}

Cheers Rolf

UPDATED: tested and works!

If you dont like the hashslice you can also use  map {\$myhash{\$_}} @allpreds instead.

Re: How to Do Multiple OR in For Loops
by toolic (Bishop) on Apr 13, 2011 at 01:44 UTC
Untested:
```my \$tp = 0;

my @allpreds = (\$pred,\$pred1,\$pred2,\$pred3,\$pred4,\$pred5,\$pred6);

foreach my \$allpred ( @allpreds ) {
if ( \$myhash{\$allpred} ) {
\$tp = 1;
last;
}
}

my \$fp = (\$tp == 1) ? 0 : 1;
```my \$fp = !!! \$tp;
!!!\$tp is the same as just !\$tp, and it's not equivalent to \$tp ? 0 : 1.
```\$ perl -E'\$tp=1; say "[", !\$tp, "]";'
[]

\$ perl -E'\$tp=1; say "[", \$tp ? 0 : 1, "]";'
[0]
Re: How to Do Multiple OR in For Loops
by Anonymous Monk on Apr 13, 2011 at 01:38 UTC
```my \$tp=0;
my \$fp=0;

my @allpreds = (\$pred,\$pred1,\$pred2,\$pred3,\$pred4,\$pred5);

foreach my \$allpred ( @allpreds ) {
if ( \$myhash{\$allpred} ) {
\$tp++;

}

}
if ( !myhash{\$pred} ) {
\$fp++;
}
__END__
Can't call method "myhash" on an undefined value at - line 13.
Re: How to Do Multiple OR in For Loops
by Anonymous Monk on Apr 13, 2011 at 01:41 UTC
```if ( grep { exists \$myhash{ \$_ } } @pred ){
\$tp++;
} else {
\$fp++;
}
Re: How to Do Multiple OR in For Loops
by JavaFan (Canon) on Apr 13, 2011 at 06:40 UTC
```my \$tp=0;
my \$fp=0;

my @allpreds = (\$pred,\$pred1,\$pred2,\$pred3,\$pred4,\$pred5);

\$fp++;
foreach my \$allpred (@allpreds) {
if (\$myhash{\$allpred}) {
\$tp++;
\$fp--;
last;
}
}
Re: How to Do Multiple OR in For Loops
by Marshall (Abbot) on Apr 13, 2011 at 09:17 UTC
Your "if" statement is very efficient. There is no need to change it unless you need to make a major expansion of the \$predX variables, probably with a @pred array. Otherwise, I see no need to re-visit and change working code.

Do not mistake fewer lines of code for greater efficiency.
However, ikegami's code looks to me to be short, efficient and uses the power of the language, ie. grep.

Note though that || short circuits (doesn't evaluate more clauses than needed to calculate the answer), where as grep will always perform all checks.

Of course, it's not very common to have so many clauses that it matters. You may need hundreds, if not thousands of clauses to make a significant difference (and then only if there's a true clause "early" enough).

I was wondering if the short circuit could cause side effects. But in this case there is no risk of auto-vivication.

With side-effects I'd rather prefer a non short circuit solution for clarity.

If a short circuit effect is side effects areš wanted, it should be done explicitly.

Cheers Rolf

Create A New User
Node Status?
node history
Node Type: perlquestion [id://899073]
Approved by ww
help
Chatterbox?
 [Corion]: A good weekstart to everybody!

How do I use this? | Other CB clients
Other Users?
Others making s'mores by the fire in the courtyard of the Monastery: (8)
As of 2018-06-18 08:16 GMT
Sections?
Information?
Find Nodes?
Leftovers?
Voting Booth?
Should cpanminus be part of the standard Perl release?

Results (109 votes). Check out past polls.

Notices?