为什么JavaScript中没有逻辑的XOR运算符?
布尔值的一行代码:
if (x ? !y : y) { do something cool }
const xor = (a, b) => !!(!!a ^ !!b)
console.log(undefined ^ {}) // Returns 0, bitwise can't be done here.
console.log(xor(undefined, {})) // Returns true, because {} is truthy and undefined is falsy
console.log(0 ^ 1) // Works naturally, returns 1
console.log(xor(0, 1)) // Also works, returns true
console.log(true ^ false) // Again, returns true
console.log(xor(true, false)) // And again, returns true...
为了好玩,这应该可以在TypeScript中工作,通过强制使用明确的 any 类型:
const xor = (a: any, b: any) => !!((!!a as any) ^ (!!b as any))
function xor(x,y){return true==(!!x!==!!y);}
function xnor(x,y){return !xor(x,y);}
(!!x) === (!!y)
相同。区别在于将其转换为布尔值。'' === 0
是假的,而 xnor('', 0)
是真的。 - tschwab在 TypeScript 中(+ 变为数字值):
value : number = (+false ^ +true)
value : boolean = (+false ^ +true) == 1
!!(false ^ true)
可以正常使用布尔值。但在TypeScript中,需要加上+才能使其有效:!!(+false ^ +true)
。 - pfgcond1 xor cond2
等价于 cond1 + cond 2 == 1
:
以下是证明:
let ops = [[false, false],[false, true], [true, false], [true, true]];
function xor(cond1, cond2){
return cond1 + cond2 == 1;
}
for(op of ops){
console.log(`${op[0]} xor ${op[1]} is ${xor(op[0], op[1])}`)
}
function xor(cond1, cond2){ return !!cond1 + !!cond2 === 1 }
。 - Chris Perry[true, false].filter(x => x).length === 1; // true, only 1 truthy
[false, true, false].filter(x => x).length === 1; // true, only 1 truthy
[true, false, true].filter(x => x).length === 1; // false, 2+ truthy
function xor(array) {
return (array ?? []).filter(x => x).length === 1;
}
xor([true, false]); // true, only 1 truthy
xor([false, true, false]); // true, only 1 truthy
xor([true, false, true]); // false, 2+ truthy
以下是一种使用2个或更多变量并提供计数奖励的备选解决方案。
这里有一个更通用的解决方案,可以模拟逻辑异或操作符的任何真假值,就像在标准IF语句中一样:
const v1 = true;
const v2 = -1; // truthy (warning, as always)
const v3 = ""; // falsy
const v4 = 783; // truthy
const v5 = false;
if( ( !!v1 + !!v2 + !!v3 + !!v4 + !!v5 ) === 1 )
document.write( `[ ${v1} XOR ${v2} XOR "${v3}" XOR ${v4} XOR ${v5} ] is TRUE!` );
else
document.write( `[ ${v1} XOR ${v2} XOR "${v3}" XOR ${v4} XOR ${v5} ] is FALSE!` );
if( ( ( v1===true ) + ( v2===true ) + ( v3===true ) + ( v4===true ) + ( v5===true ) ) === 1 )
// etc.
如果您不关心计数,或者如果您关心最佳性能:那么只需对强制转换为布尔值的值使用按位异或运算符,以获得真/假解决方案:
if( !!v1 ^ !!v2 ^ !!v3 ^ !!v4 ^ !!v5 )
// etc.
这里提出的大多数方法都很难阅读和理解。与其编写一些神秘的比较或试图对它们进行注释,不如定义一个可重复使用且自我解释的函数:
function either(a: boolean, b: boolean): boolean {
return (a !== b);
}
或者更通用的一个:
function either(a: any, b: any): boolean {
return Boolean(a) !== Boolean(b);
}
然后你可以像这样使用它:
assert(either(one, another), 'Either one or another, not both');
嘿,我找到了一个解决方案,在JavaScript和TypeScript上进行XOR操作。
if( +!!a ^ +!!b )
{
//This happens only when a is true and b is false or a is false and b is true.
}
else
{
//This happens only when a is true and b is true or a is false and b is false
}
!
符号已经将操作数转换为布尔值。这意味着所有 +
做的就是将 true
或 false
转换为 1
或 0
,在这种情况下两者产生的结果都是相同的。同时也值得注意的是,!!a ^ !!b
等价于 !a ^ !b
。 - zcoop98