是否有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) { ... } 

http://www.howtocreate.co.uk/xor.html

您可以直接使用按位XOR运算符( ^ ):

 if (isEmptyString(firstStr) ^ isEmptyString(secondStr)) { // ... } 

它将适用于您的示例,因为布尔值truefalse值被转换为10因为按位运算符使用32位整数。

该expression式也会返回01 ,并且该值将被if语句强制回到布尔值。

你应该知道使用上述方法时发生的types强制,如果你正在寻找良好的性能,我不build议你使用按位运算符,你也可以使用一个简单的函数来使用布尔逻辑运营商:

 function xor(x, y) { return (x || y) && !(x && y); } if (xor(isEmptyString(firstStr), isEmptyString(secondStr))) { // ... } 

更简单的一种方法:

 if ((x+y) % 2) { //statement } 

当然假设两个variables都是真正的布尔值,即10

  • 如果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)); } 

上述来源于“排斥”的定义{任一个,但不是两个}。

由于布尔值truefalse在使用按位运算符时分别被转换为10 ,因此只要您的值是布尔值,则按位异或可作为逻辑异或双精度执行双重任务( Javascript的“truthy”值不会工作)。 这很容易达到否定! 运营商。

a XOR b在逻辑上等同于下面的(简称)expression式列表:

 !a ^ !b; !a != !b; 

还有很多其他可能的forms – 例如!a ? !!b : !b !a ? !!b : !b – 但是这两种模式的优点是每次只评估ab (如果a是假的,也不会“短路”,因此不会评估b ),而使用三元forms的forms?: OR || ,或AND &&运营商将会进行双重评估或短路。

否定! 这两个语句中的运算符是很重要的,包括几个原因:它将所有“真值”转换为布尔值(“” – > false,12 – > true等),以便位运算符具有可以使用的值,因此,不等式!=运算符只会比较每个expression式的真值(如果ab是非相等的非空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似乎是一个选项。

http://jsperf.com/xor-implementations

你可以这样做:

 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; }