在给定的多个条件中,如何检查是否有多个条件为真 - PHP

8

有没有一种优雅的方法可以检查给定数量的条件中是否有多个,但不是全部满足?

例如,我有三个变量:$a、$b 和 $c。 我想要检查其中任意两个是否为真。以下情况将会通过:

$a = true;
$b = false;
$c = true;

但这不会:
$a = false;
$b = false;
$c = true;

另外,我想检查是否有7个条件中的4个为真。
我知道可以逐个检查每种组合,但是随着条件数量的增加,这将变得更加困难。遍历条件并保持总数是我能想到的最佳选择,但我认为可能有不同的方法来解决这个问题。
谢谢!
编辑:感谢所有出色答案的回答,非常感谢。 如果变量不是明确的布尔值会怎样呢? 例如。
($a == 2)
($b != "cheese")
($c !== false)
($d instanceof SomeClass)

你想要“超过1个但不是全部”,还是你想要“恰好x个中的y个”? - Erik
你有变量的数量吗?例如,第一个案例是3,第二个案例是7。 - Alok Patel
我正在寻找一种适用于不同情况的灵活解决方案。理想情况下,一个具有范围选项(即在7个选项中选择2到4个)的解决方案将是很好的选择。但是,如果有必要,该解决方案也可以用于表示“2到2之间”——即恰好为2。 - Six Ticks Limited
我认为没有什么比循环条件并跟踪它们更优雅的了。你可以编写一些接受数组和数字的函数,但也就仅此而已。 - Erik
你的最新需求不应该对程序造成任何影响,因为你提供的所有表达式都会产生布尔值;在评估这些表达式和评估布尔变量之间不应该有任何区别。例如,尝试使用 var_dump($d instanceof SomeClass);;你会发现结果将是 bool(false),这表明你已经得到了一个明确的布尔值作为结果。 - Matt Gibson
6个回答

11

这在同样的方式中是否能正常工作: ($a == 2) + ($b != "cheese") + ($c !== false)? - Six Ticks Limited
1
是的,每个测试都会返回“true”或“false”。 - Tigger

5

您可以将变量放入数组中,并使用array_filter()count()来检查真值的数量:

$a = true;
$b = false;
$c = true;

if (count(array_filter(array($a, $b, $c))) == 2) {
    echo "Success";
};

1
根据 OP 的说法,所有变量都不应该是 true - Alok Patel
@AlokPatel 明白了,已更新。 - Robby Cornelissen
你可能需要在array_filter的计数中添加||。它应该大于或等于2,并且不应该是所有变量的总和。 - Alok Patel
@AlokPatel 为什么?array_filter()过滤掉所有的true值,而count()计算该操作的结果。根据OP的说法,应该有任意两个是true,因此使用严格相等。 - Robby Cornelissen
@AlokPatel OP 表示:“我想检查这些中是否有任意两个是真的。” 如果两个或更多也可以,那么条件应该改为大于或等于而不是等于,就这样。 - Robby Cornelissen
显示剩余5条评论

1
我会选择以下类似的方法:

if (evaluate(a, b, c))
{
    do stuff;
}

boolean evaluate(boolean a, boolean b, boolean c) 
{
    return a ? (b || c) : (b && c);
}

这段话的意思是:

  • 如果a为True,那么b或c中必须至少有一个也为True以符合2/3 True标准。
  • 否则,b和c都必须为True!

如果您想扩展和自定义条件以及变量数量,可以考虑以下解决方案:

$a = true;
$b = true;
$c = true;
$d = false;
$e = false;
$f = true;

$condition = 4/7;

$bools = array($a, $b, $c, $d, $e, $f);

$eval = count(array_filter($bools)) / sizeof($bools);

print_r($eval / $condition >= 1 ? true : false);

我们只需评估真实值,并确保True的百分比等于或优于我们想要达到的目标。同样,您可以操纵最终评估表达式以实现您想要的结果。


我不太明白“7个中的4个”是什么意思。他是指7个布尔表达式中的4个吗? - Manu
@Manos,真的很不错。 - Blinkydamo
@ManosForsaken 是的,我想知道是否有一种灵活的解决方案,可以处理任意数量的条件中的任意数量的真条件。目前我只需要其中的三个条件中的两个,但将来可能需要其他数量的条件。 - Six Ticks Limited

1
这也应该有效,并且可以让你相对容易地调整数字。
$a = array('soap','soap');
$b = array('cake','sponge');
$c = array(true,true);
$d = array(5,5);
$e = false;
$f = array(true,true);
$g = array(false,true);
$pass = 4;
$ar = array($a,$b,$c,$d,$e,$f,$g);

var_dump(trueornot($ar,$pass));

function trueornot($number,$pass = 2){
    $store = array();
    foreach($number as $test){
        if(is_array($test)){
            if($test[0] === $test[1]){
                $store[] = 1;
            }
        }else{
            if(!empty($test)){
                $store[] = 1;   
            }
        }    
        if(count($store) >= $pass){
            return TRUE;    
        }
    }
    return false;
}

谢谢,这看起来对于布尔变量很好 - 尽管需要一些调整才能适用于其他类型的变量。 - Six Ticks Limited
@SixTicksLimited,现在应该可以了。 - Epodax

0

我认为当你使用运算符"&"和"|"时,它会变得更加简单和简短:

$a = true;
$b = true;
$c = false;

$isTrue = $a&$b | $b&$c | $c&$a;

print_r( $isTrue );

让你自己来检查 :D


0

你可以使用 while 循环:

$condition_n = "x number"; // number of required true conditions
$conditions = "x number"; // number of conditions
$loop = "1";
$condition = "0";

while($loop <= $conditions)
{
 // check if condition is true
 // if condition is true : $condition = $condition + 1;
 // $loop = $loop + 1;
}
if($condition >= $condition_n)
{
 // conditions is True
}
else
{
 // conditions is false
}

是的,这就是我在问题中建议的那种循环——只是看起来有点啰嗦。 - Six Ticks Limited

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接