开发者

How can I rewrite this multiple OR condition so that it uses a Perl "for" loop?

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 in total of fp and tp:

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++;
    }


my $tp=0;
my $fp=0;
my $count=0;

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

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

        }

    }

if ($count>0) { $tp=1; } else { $fp=1; }


This is somewhat more compact than some answers, but fully equivalent.

my $tp = 0;
my $fp = 0;

foreach my $allpred ($pred, $pred1, $pred2, $pred3, $pred4, $pred5)
{
    $tp++, last if ($myhash{$allpred});
}

$fp = !$tp;

It is not clear that the variable $fp earns its keep when !$tp is almost as simple to write.


Test code - change the settings on the RHS of the fat commas to change the behaviour of the test.

use strict;
use warnings;

my $pred   = "";
my $pred1  = "1";
my $pred2  = "2 2";
my $pred3  = "3 3 3";
my $pred4  = "4 4 4 4";
my $pred5  = "5 5 5 5 5";
my %myhash = ( $pred1 => 0, $pred2 => 0, $pred3 => 0, $pred4 => 0, $pred5 => 1 );

my $tp = 0;
my $fp = 0;

foreach my $allpred ($pred, $pred1, $pred2, $pred3, $pred4, $pred5)
{
    $tp++, last if ($myhash{$allpred});
}

$fp = !$tp;

printf "%d:%d\n", $tp, $fp;


grep will return a true value when any one or more of its inputs returns true for it's statement, basically allowing it to act like a chain of ||'ed statements, except that it won't short circuit.

my @allpreds = ($pred, $pred1, $pred2, $pred3, $pred4, $pred5, $pred6);
if (grep { $myhash{$_} } @allpreds) {
    $tp++;
}
else {
    $fp++;
}

Using grep this way can be a bit confusing so a more explicit way is to use List::MoreUtils any

use List::MoreUtils qw(any);
my @allpreds = ($pred, $pred1, $pred2, $pred3, $pred4, $pred5, $pred6);
if (any { $myhash{$_} } @allpreds) {
    $tp++;
}
else {
    $fp++;
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜