Php 确保给定列表中只有一个布尔值为真?
如果我有以下布尔值Php 确保给定列表中只有一个布尔值为真?,php,xor,boolean-logic,boolean-operations,Php,Xor,Boolean Logic,Boolean Operations,如果我有以下布尔值 const YESTERDAY = false; const TODAY = true; const TOMORROW = false; 我可以编写什么代码来确保其中一个是正确的 我试过这个: $x = self::YESTERDAY ^ self::TODAY ^ self::TOMORROW; 问题是,当所有三个常量都设置为true时,$x就是true$x=((int)self::昨天)+((int)self::今天)+(int)self::明天)
const YESTERDAY = false;
const TODAY = true;
const TOMORROW = false;
我可以编写什么代码来确保其中一个是正确的
我试过这个:
$x = self::YESTERDAY ^ self::TODAY ^ self::TOMORROW;
问题是,当所有三个常量都设置为true
时,$x
就是true$x=((int)self::昨天)+((int)self::今天)+(int)self::明天)如果$x===1代码>你已经得到了你所需要的
编辑:
即使没有类型强制转换(int)
,由于@DaveRandom,它也能正常工作,因此:
如果(self::昨天+self::今天+self::明天==1){}
,对我来说。这是devdRew回答的另一种选择
$x = array_count_values(array((int) self::YESTERDAY,(int) self::TODAY,(int) self::TOMORROW));
if (isset($x[1]) && $x[1] == 1) {
echo 'Only one TRUE';
}
我能想到的最整洁的方式是:
编辑实际上,您只需在最初的尝试中将^
替换为+
,即可实现同样的效果:
$x = self::YESTERDAY + self::TODAY + self::TOMORROW;
这将$x
转换为TRUE
值的数量。因此,对于布尔输出,请使用:
$ok = self::YESTERDAY + self::TODAY + self::TOMORROW === 1;
您可以在变量列表上循环,并在发现第二个布尔值为true时中断:
$moreThanOneTrue=false;
$oneTrue;
foreach ($BOOL_VAR_ARRAY as $bool) {
if ($bool) {
if($oneTrue) {
$moreThanOneTrue=true;
break;
}
$oneTrue=true;
}
}
这样,当您有三个以上的变量时,它会更方便。x将返回true,当且仅当其中一个为true,其他为false
$x = ($a && !($b || $c)) || ($b && !($a || $c)) || ($c && !($a || $b));
可能是一个糟糕的代码,但很有效。a^b^c^(a&b&c)
是您要查找的表达式。您可以使用或条件将所有组合放入(昨天=真,今天=假,明天=假)或(昨天=假,今天=真,明天=假)或(昨天=假,今天=假,明天=真)
他需要确保true是绝对正确的,而不是至少一个。我考虑过这一点,但最好避免所有额外的处理,有没有按位的方法可以做到这一点?+1这个-在测试后,似乎你甚至不需要(int)
强制转换,它是隐式发生的。这比任何其他解决方案都要整洁@Matt在使用XOR(^)运算符时几乎是正确的,但不幸的是,true^true^true
将计算为true
,因为PHP将其解释为(true^true)^true
,即false^true
,这是一个惊人的解决方案。谢谢:实际上,devdRew答案的一个变体是最简洁的-如果你只是在原始代码中用+
替换^
,它也会做同样的事情-你不需要(int)
强制转换,因为这种情况是隐式发生的。如果超过3个,我认为数组
方法会比这简单
$x = ($a && !($b || $c)) || ($b && !($a || $c)) || ($c && !($a || $b));