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++;
}
精彩评论