Удостоверьтесь, что только один логический элемент из данного списка верен? - PullRequest
8 голосов
/ 30 января 2012

Если у меня есть следующие логические значения

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

Какой код я могу написать, чтобы убедиться, что точно один из них верен?

Я пробовал это:

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

Проблема в том, что если для всех трех констант установлено значение true, то $x равно true.

Ответы [ 6 ]

9 голосов
/ 30 января 2012

$x = ((int) self::YESTERDAY) + ((int) self::TODAY) + ((int) self::TOMORROW); Тогда, если $x === 1; Вы получите то, что вам нужно.

РЕДАКТИРОВАНИЕ:

Даже без приведения типов (int) работает хорошо, благодаря @DaveRandom, поэтому:

if (self::YESTERDAY + self::TODAY + self::TOMORROW == 1) {}, как по мне.

3 голосов
/ 30 января 2012

Самый простой способ, о котором я могу думать, это 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;
0 голосов
/ 22 сентября 2014

a ^ b ^ c ^ (a & b & c) - это выражение, которое вы ищете.

0 голосов
/ 30 января 2012

x вернет true, если и только если один верен, а другие ложны.

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

Может быть плохой код, но работает.

0 голосов
/ 30 января 2012

Вы можете перебрать список своих переменных и оборвать их, когда найдете второе логическое значение, которое имеет значение true:

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

Подобно этому, это более удобно, когда у вас более трех переменных.

0 голосов
/ 30 января 2012

Так же, как альтернатива ответу 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';
}
...