是否有JavaScript来实现异或
我试图通过以下方式在JavaScript中实现XOR:
// XOR validation if ((isEmptyString(firstStr) && !isEmptyString(secondStr)) || (!isEmptyString(firstStr) && isEmptyString(secondStr)) { alert(SOME_VALIDATION_MSG); return; }
有没有更好的方式来做到这一点的JavaScript?
谢谢。
我假装你正在寻找一个逻辑异或,因为JavaScript已经有一个按位(^):)
我通常使用一个简单的三元操作符(我使用其中的一种):
if ((isEmptyString(firstStr) ? !isEmptyString(secondStr) : isEmptyString(secondStr))) { alert(SOME_VALIDATION_MSG); return; }
编辑:
在@Jeff肉丸杨解决scheme
if ((!isEmptyString(firstStr) ^ !isEmptyString(secondStr))) { alert(SOME_VALIDATION_MSG); return; }
你否定这些值,以便在布尔变换它们,然后应用按位异或运算符。 也许它不像第一个解决scheme那么可维护(或者我可能习惯了第一个解决scheme)
正如其他人所指出的那样,逻辑XOR与布尔运算符不同,所以你可以这样做:
// XOR validation if( isEmptyString(firstStr) != isEmptyString(secondStr) ) { alert(SOME_VALIDATION_MSG); return; }
你正在做一个布尔值的异或,这很容易build模成一个按位异或(这是JavaScript有):
var a = isEmptyString(firstStr) ? 1 : 0; var b = isEmptyString(secondStr) ? 1 : 0; if(a ^ b) { ... }
您可以直接使用按位XOR运算符( ^
):
if (isEmptyString(firstStr) ^ isEmptyString(secondStr)) { // ... }
它将适用于您的示例,因为布尔值true
和false
值被转换为1
和0
因为按位运算符使用32位整数。
该expression式也会返回0
或1
,并且该值将被if
语句强制回到布尔值。
你应该知道使用上述方法时发生的types强制,如果你正在寻找良好的性能,我不build议你使用按位运算符,你也可以使用一个简单的函数来使用布尔逻辑运营商:
function xor(x, y) { return (x || y) && !(x && y); } if (xor(isEmptyString(firstStr), isEmptyString(secondStr))) { // ... }
更简单的一种方法:
if ((x+y) % 2) { //statement }
当然假设两个variables都是真正的布尔值,即1
或0
。
- 如果
x === y
你会得到一个偶数,所以XOR将会是0
。 - 如果
x !== y
那么你会得到一个奇数,所以异或将是1
🙂
第二个选项,如果你注意到x != y
评估为异或,那么你所要做的就是
if (x != y) { //statement }
这将只是评估,再次,作为异或。 (我更喜欢这个)
当然,一个不错的想法是将其实现为一个函数,但这只是您的select。
希望这两种方法有助于某人! 我把这个答案标记为社区wiki,所以可以改进。
在javascript中检查XOR的不同实现的这个解释。
只是在这里总结一些他们:
if( ( isEmptyString(firstStr) || isEmptyString(secondStr)) && !( isEmptyString(firstStr) && isEmptyString(secondStr)) ) { alert(SOME_VALIDATION_MSG); return; }
要么
if( isEmptyString(firstStr)? !isEmptyString(secondStr): isEmptyString(secondStr)) { alert(SOME_VALIDATION_MSG); return; }
要么
if( (isEmptyString(firstStr) ? 1 : 0 ) ^ (isEmptyString(secondStr) ? 1 : 0 ) ) { alert(SOME_VALIDATION_MSG); return; }
要么
if( !isEmptyString(firstStr)!= !isEmptyString(secondStr)) { alert(SOME_VALIDATION_MSG); return; }
从这篇文章引用:
不幸的是,JavaScript没有逻辑异或运算符。
你可以像下面这样“模拟”XOR运算符的行为:
if( !foo != !bar ) { ... }
链接的文章讨论了一些替代方法。
异或只是意味着“这两个布尔值是不同的?”。 因此:
if (!!isEmptyString(firstStr) != !!isEmptyString(secondStr)) { // ... }
!!
s只是保证!=
运算符比较两个真正的布尔值,因为可以想象的是, isEmptyString()
返回其他的东西(比如null
为false,或者string本身为true)。
假设你正在寻找BOOLEAN XOR,这里是一个简单的实现。
function xor(expr1, expr2){ return ((expr1 || expr2) && !(expr1 && expr2)); }
上述来源于“排斥”的定义{任一个,但不是两个}。
由于布尔值true
和false
在使用按位运算符时分别被转换为1
和0
,因此只要您的值是布尔值,则按位异或可作为逻辑异或双精度执行双重任务( Javascript的“truthy”值不会工作)。 这很容易达到否定!
运营商。
a XOR b
在逻辑上等同于下面的(简称)expression式列表:
!a ^ !b; !a != !b;
还有很多其他可能的forms – 例如!a ? !!b : !b
!a ? !!b : !b
– 但是这两种模式的优点是每次只评估a
和b
(如果a
是假的,也不会“短路”,因此不会评估b
),而使用三元forms的forms?:
OR ||
,或AND &&
运营商将会进行双重评估或短路。
否定!
这两个语句中的运算符是很重要的,包括几个原因:它将所有“真值”转换为布尔值(“” – > false,12 – > true等),以便位运算符具有可以使用的值,因此,不等式!=
运算符只会比较每个expression式的真值(如果a
或b
是非相等的非空string, a != b
将无法正常工作),并且每个计算结果都会返回一个布尔值结果的第一个“真理”价值。
您可以通过添加双重否定(或exception, !!a ^ !!b
,它仍然等同于XOR)来继续扩展这些表单,但是在否定部分expression式时要小心。 如果你想用算术分布(其中2(a + b) == 2a + 2b
等)来思考这些forms,那么这些forms可能乍看上去是“有效的”,但事实上从异或这些产生与逻辑NXOR类似的结果 ):
!( a ^ b ) !( !!a ^ !!b ) !!a == !!b
那么异或的一般forms可以是函数( 真值表小提琴 ):
function xor( a, b ) { return !a ^ !b; }
而你的具体例子则是:
if ( xor( isEmptyString( firstStr ), isEmptyString( secondStr ) ) ) { ... }
或者,如果isEmptyString
只返回布尔值,并且您不需要一般的xor
函数,那么只需:
if ( isEmptyString( firstStr ) ^ isEmptyString( secondStr ) ) { ... }
Javascript没有一个逻辑XOR操作符,所以你的构造似乎是合理的。 如果它是数字,那么你可以使用^即按位XOR运算符。
干杯
这里是一个可以容纳两个到多个参数的XOR
function XOR() { for (var i = 1; i < arguments.length; i++) if ( arguments[0] != arguments[i] ) return false; return true; }
使用示例:
if ( XOR( isEmptyString(firstStr), isEmptyString(secondStr) ) ) { alert(SOME_VALIDATION_MSG); return; }
我希望这将是最短和最干净的
function xor(x,y){return true==(x!==y);}
这将适用于任何types
这里是一个XOR函数,它使用可变数量的参数(包括两个参数)。 这些论据只需要是true
或者是false
,而不是true
或者false
。
function xor() { for (var i=arguments.length-1, trueCount=0; i>=0; --i) if (arguments[i]) ++trueCount; return trueCount & 1; }
在我2007 MacBook的Chrome上,它运行在14纳秒三个参数。 奇怪的是,这个略有不同的版本需要2935 ns的三个参数:
function xorSlow() { for (var i=arguments.length-1, result=false; i>=0; --i) if (arguments[i]) result ^= true; return result; }
试试这个: function xor(x,y) var result = x || y if (x === y) { result = false } return result }
function xor(x,y) var result = x || y if (x === y) { result = false } return result }
有几种方法,但三元法(a?!b:b)performance最好。 另外,如果你需要经常使用异或,设置Boolean.prototype.xor似乎是一个选项。
你可以这样做:
Math.abs( isEmptyString(firstStr) - isEmptyString(secondStr) )
其结果是异或操作的结果。
@george,我喜欢你的function,因为它能够接受两个以上的操作数。 我有一个小小的改进,使其返回更快:
function xor() { for (var i=arguments.length-1, trueCount=0; i>=0; --i) if (arguments[i]) { if (trueCount) return false ++trueCount; } return trueCount & 1; }