【问题标题】:Make sure exactly one boolean of a given list is true?确保给定列表的一个布尔值是真的?
【发布时间】:2012-01-30 11:28:13
【问题描述】:

如果我有以下布尔值

const YESTERDAY = false;
const TODAY = true;
const TOMORROW = false;

我可以编写什么代码来确保其中一个是真的?

我试过了:

$x = self::YESTERDAY ^ self::TODAY ^ self::TOMORROW;

问题是所有三个常量都设置为true,那么$x 就是true

【问题讨论】:

  • 你可以使用 OR 条件(YESTERDAY=true AND TODAY=false AND TOMORROW=false) or (YESTERDAY=false AND TODAY=true AND TOMORROW=false) or (YESTERDAY=false AND TODAY=false AND TOMORROW=true)
  • 他需要确定真实的是一个,而不是至少一个。

标签: php xor boolean-logic boolean-operations


【解决方案1】:

$x = ((int) self::YESTERDAY) + ((int) self::TODAY) + ((int) self::TOMORROW); 那么如果$x === 1; 你得到了你需要的东西。

已编辑:

即使没有类型转换 (int),它也能正常工作,这要感谢 @DaveRandom,所以:

if (self::YESTERDAY + self::TODAY + self::TOMORROW == 1) {},至于我。

【讨论】:

  • 我想过这个,但最好避免所有额外的处理,有没有按位的方法来做到这一点?
  • +1 this - 经过测试,您似乎甚至不需要 (int) 强制转换,它是隐式发生的。
  • 这比任何其他解决方案都要整洁。 @Matt 在使用 XOR (^) 运算符时几乎是正确的,但不幸的是 true ^ true ^ true 将计算为 true,因为 PHP 将其解释为 (true ^ true) ^ true,即 false ^ true
  • 这是一个了不起的解决方案。谢谢:D
【解决方案2】:

我能想到的最简洁的方式是array_sum()

if (array_sum(array(self::YESTERDAY, self::TODAY, self::TOMORROW)) == 1) {
  // Do something
}

编辑实际上,您只需在最初的尝试中将^ 替换为+,就可以达到同样的效果:

$x = self::YESTERDAY + self::TODAY + self::TOMORROW;

这会将$x 转换为TRUE 值的数量。所以对于布尔输出使用:

$ok = self::YESTERDAY + self::TODAY + self::TOMORROW === 1;

【讨论】:

  • 实际上 devdRew 的答案的变体是最简洁的 - 如果您只是在原始代码中将 ^ 替换为 + 它会做同样的事情 - 您不需要 (int) 演员表因为这是隐含地发生的。
【解决方案3】:

作为 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';
}

【讨论】:

    【解决方案4】:

    您可以遍历变量列表并在发现第二个布尔值为真时中断:

    $moreThanOneTrue=false;
    $oneTrue;
    foreach ($BOOL_VAR_ARRAY as $bool) {
        if ($bool) {
            if($oneTrue) {
                $moreThanOneTrue=true;
                break;
            }
            $oneTrue=true;
        }
    }
    

    当你有三个以上的变量时,这样会更方便。

    【讨论】:

    • 如果超过3个我认为array_sum方法会比这个更简单
    【解决方案5】:

    当且仅当一个为真而其他为假时,x 才会返回真。

    $x = ($a && !($b || $c)) || ($b && !($a || $c)) || ($c && !($a || $b));
    

    可能是一个糟糕的代码,但可以工作。

    【讨论】:

      【解决方案6】:

      a ^ b ^ c ^ (a & b & c) 是您要查找的表达式。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2010-09-27
        • 1970-01-01
        • 2016-09-28
        • 2014-12-05
        • 2013-01-31
        • 1970-01-01
        • 2019-01-25
        相关资源
        最近更新 更多