如何重写这个多OR条件,以便它使用Perl" for"环?

时间:2011-04-13 01:25:03

标签: linux perl unix loops for-loop

我有一个硬编码的if循环,如下所示:

my $tp = 0;
my $fp = 0;
if (   $myhash{$pred}
        || $myhash{$pred1}
        || $myhash{$pred2}
        || $myhash{$pred3}
        || $myhash{$pred4}
        || $myhash{$pred5}
        || $myhash{$pred6} )
    {
        $tp++;
    }
    else {
        $fp++;
    }

我怎么能在for循环中做到这一点?

我尝试了以下操作,但它在fptp的总计中得出了不同的结果:

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

3 个答案:

答案 0 :(得分:3)

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

答案 1 :(得分:1)

这比某些答案更紧凑,但完全相同。

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

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

$fp = !$tp;

$fp几乎一样简单时,变量!$tp获得保留并不清楚。


测试代码 - 更改胖逗号的RHS设置以更改测试的行为。

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;

答案 2 :(得分:1)

grep的任何一个或多个输入为它的语句返回true时,它将返回一个真值,基本上允许它像一串||'ed语句一样,除了它赢了' t短路。

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

使用grep这种方式可能有点令人困惑,所以更明确的方法是使用List::MoreUtils any

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