检查三个布尔值中是否恰好有两个为真?

7

我需要测试是否恰好有三个布尔值中的两个为真。

类似于这样:

if ((a && b && !c) || (a && !b && c) || (!a && b && c)) {
  // success
}

这是最直接的方法吗?有没有人知道快捷方式或速记?


请查看这个答案 - user2314737
我看到了那个,但是我的问题不同,因为那种情况是“至少”其中两个成立......这意味着第三个也可能是真的,但在我的情况下不是。 - WillD
8个回答

14

6

如果您将这些值相加,可以检查结果是否为2

if ((a + b + c) == 2) {
    // do something
}

谢谢。我忘记在JS中布尔值只是1和0。 - WillD
你能解释一下为什么吗? - ave4496
@RichardAyotte 在英国,如果你这样做,程序员可能有不公正解雇的理由.. :) - Keith
如果您将其放入一个具有有用名称的函数中,它就是自说明的。我只是回答了他的问题,并假设他会将代码放入一个函数中。 - ave4496
1
@RichardAyotte “cacophemism” 是的,我明白了,这个笑脸的原因是……这并不是什么诡计,这就是JS的特性,但你提到的“显而易见”的观点完全正确。虽然更长,但使用 Number(a) + Number(b) + Number(c) 更容易让其他程序员看出你的意图。我完全支持程序员编写易于理解的代码。 - Keith
或者使用(!a + !b + !c) ==1更明显地测试它们中只有一个是假的? - traktor

1
我会这样翻译(在我看来比较易读):

我会选择这种易读的方式:

let conditions = [a && b && !c, a && !b && c, !a && b && c]
if(conditions.filter(c => c).length === 2) { /* ... */}

1

你甚至不需要转换它们。

let a = true;
let b = true;
let c = false;

if(a + b + c === 2) {
    console.log('You won!');
} else {
    console.log('Not 2');
}

嗯,那仍然会将它们转换。 (我并不认为这是一个不好的解决方案,但显然有些人不喜欢它。)在这里进行转换的不是 ==,而是 +,它会将布尔值隐式转换为数字。(通常情况下,如果其中一个参数已经是字符串,则我认为 + 会将另一个参数转换为字符串,否则它会将它们都转换为数字。) - Robin Zigmond

0

你可以将这些布尔值转换(强制转换)为整数并将它们相加。然后检查它是否等于2。像这样(C语言):

int res = (int)a + (int)b + (int)c;
if (res == 2) { /* Do something... */ }

编辑:

对于 JavaScript,你甚至不需要转换数值类型:

const res = a + b + c
if (res == 2) { /* Do something... */ }

2
你的答案几乎正确,但这是Javascript而不是C,所以你的语法是错误的。 :) - Keith
@Keith 更新了答案。 - comonadd

0
如果您想多次检查三个布尔值中是否恰好有两个为真,可以使用函数来缩短代码。

function boolTest(a, b, c) {
    if ((a && b && !c) || (a && !b && c) || (!a && b && c)) {
        return true
    } else {
        return false
    }
}

然后,您可以像这样使用它:

boolTest(true, true, false) // returns true
boolTest(false, true, false) // returns false


0
在JavaScript(以及大多数其他现代编程语言)中,布尔变量可以存储为二进制整数(10),并且这些整数可以用作布尔值。请参见以下示例:

if (1) {
    console.log("1 is true");
} else {
    console.log("1 is false");
}

if (0) {
    console.log("0 is true");
} else {
    console.log("0 is false");
}

因此,要检查三个布尔值中的两个,您可以这样做:

var a = true;
var b = false;
var c = true;

var total = (a ? 1 : 0) + (b ? 1 : 0) + (c ? 1 : 0);
if (total == 2) {
    console.log("Success!");
}

希望这能有所帮助!


0

a=true;
b=true;
c=false;
arr = [a,b,c]
result = arr.reduce((acc, cur) => acc+cur) == 2;

console.log(result);

这种方法的优点包括:

  • 无需转换为布尔值
  • 易于推广到任意大小/任意数量的真值数组

对于更长的数组,可以考虑一种性能更好的解决方案,该解决方案在达到所需数字后立即停止求和。

n=2
// large array
arr=[true,true,true].concat(Array(10000).fill(false))

// reduce will stop as soon as result is >n
result = arr.slice(0).reduce((acc, cur, i, a) => {acc+=cur; if (acc>n) a.splice(1); return acc});
console.log(result==2)


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