无论如何在javascript中实现XOR

时间:2010-02-25 17:10:00

标签: javascript validation xor

我正试图通过以下方式在javascript中实现XOR:

   // XOR validation
   if ((isEmptyString(firstStr) && !isEmptyString(secondStr)) ||
    (!isEmptyString(firstStr) && isEmptyString(secondStr))
   {
    alert(SOME_VALIDATION_MSG);
    return;
   }

在javascript中有更好的方法吗?

感谢。

18 个答案:

答案 0 :(得分:55)

正如其他人所指出的那样,逻辑XOR与布尔值不相等,所以你可以这样做:


  // XOR validation
  if( isEmptyString(firstStr) != isEmptyString(secondStr) )
    {
      alert(SOME_VALIDATION_MSG);
      return;
    }

答案 1 :(得分:34)

我假装你正在寻找一个逻辑XOR,因为javascript已经有一个按位(^):)

我通常使用一个简单的三元运算符(我很少使用其中一个):

if ((isEmptyString(firstStr) ? !isEmptyString(secondStr) 
                             : isEmptyString(secondStr))) {
alert(SOME_VALIDATION_MSG);
    return;
}

编辑:

致力于@Jeff Meatball Yang solution

if ((!isEmptyString(firstStr) ^ !isEmptyString(secondStr))) {
  alert(SOME_VALIDATION_MSG);
  return;
}

你否定这些值以便在布尔值中转换它们然后应用按位xor运算符。也许它不像第一个解决方案那么可维护(或者我可能已经习惯了第一个解决方案)

答案 2 :(得分:11)

你正在做一个布尔值的XOR,很容易建模成一个按位XOR(Javascript有):

var a = isEmptyString(firstStr) ? 1 : 0;
var b = isEmptyString(secondStr) ? 1 : 0;

if(a ^ b) { ... }

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

答案 3 :(得分:8)

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

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

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

该表达式也将返回01,并且该值将通过if语句强制回布尔值。

你应该知道上面的方法发生的类型强制,如果你正在寻找良好的性能,我不建议你使用按位运算符,你也可以使用一个简单的函数来做到这一点只有布尔逻辑运算符:

function xor(x, y) {
  return (x || y) && !(x && y);
}


if (xor(isEmptyString(firstStr), isEmptyString(secondStr))) {
  // ...
}

答案 4 :(得分:7)

更容易的一种方法:

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

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

  • 如果x === y您将获得偶数,那么XOR将为0
  • 如果x !== y那么你会得到一个奇数,那么XOR将是1:)

第二个选项,如果您注意到x != y评估为异或,那么您必须做的就是

if (x != y) {
    //statement
}

这将再次评估为异或。 (我更喜欢这个)

当然,一个好主意是将它实现到一个函数中,但它只是你的选择。

希望这两种方法中的任何一种都可以帮到某人!我将此答案标记为社区维基,因此可以对其进行改进。

答案 5 :(得分:5)

引自this文章:

  

不幸的是,JavaScript没有逻辑XOR运算符。

您可以通过以下方式“模拟”XOR运算符的行为:

if( !foo != !bar ) {
  ...
}

链接的文章讨论了几种替代方法。

答案 6 :(得分:5)

结帐this解释javascript中不同的XOR实现。

在这里总结一下:

if( ( isEmptyString(firstStr) || isEmptyString(secondStr)) && !( isEmptyString(firstStr) && isEmptyString(secondStr)) ) {
   alert(SOME_VALIDATION_MSG); 
   return; 
}

OR

if( isEmptyString(firstStr)? !isEmptyString(secondStr): isEmptyString(secondStr)) {
   alert(SOME_VALIDATION_MSG); 
   return;
}

OR

if( (isEmptyString(firstStr) ? 1 : 0 ) ^ (isEmptyString(secondStr) ? 1 : 0 ) ) {
   alert(SOME_VALIDATION_MSG); 
   return;
}

OR

if( !isEmptyString(firstStr)!= !isEmptyString(secondStr)) {
   alert(SOME_VALIDATION_MSG); 
   return;
}

答案 7 :(得分:2)

XOR只是意味着“这两个布尔值是不同的吗?”。因此:

if (!!isEmptyString(firstStr) != !!isEmptyString(secondStr)) {
    // ...
}

!!只是为了保证!=运算符比较两个真正的布尔值,因为可以想象isEmptyString()返回其他内容(如null表示false,或者字符串本身为真)。

答案 8 :(得分:2)

由于布尔值truefalse在使用按位运算符时分别转换为10,因此按位-XOR ^可以只要您的值是布尔值(Javascript的“truthy”值不起作用),可以将双重任务作为逻辑XOR和bitwiseone进行操作。使用否定!运算符很容易实现。

a XOR b在逻辑上等同于以下(短)表达式列表:

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

还有许多其他形式可能 - 例如!a ? !!b : !b - 但这两种模式的优点是每次只评估ab(并且不会“短路” “如果a为假,因此未评估b),那么使用三元?:,OR ||或AND &&运算符的表单将会加倍评估或短路。

两个语句中的否定!运算符非常重要,原因如下:它将所有“truthy”值转换为布尔值(“” - > false,12 - > true等)因此,按位运算符具有可以使用的值,因此不等式!=运算符仅比较每个表达式的真值(如果a != ba b,则!!a ^ !!b将无法正常工作非相等,非空字符串等),以便每个评估返回一个布尔值结果而不是第一个“真实”值。

您可以通过添加双重否定(或异常,2(a + b) == 2a + 2b,仍然等效于XOR)继续扩展这些表单,但在否定表达式的一部分时要小心。如果你在算术中考虑分布(!( a ^ b ) !( !!a ^ !!b ) !!a == !!b 等),这些形式似乎乍一看“工作”,但实际上从XOR(these produce similar results to logical NXOR)产生不同的真值表:

function xor( a, b ) { return !a ^ !b; }

然后,XOR的一般形式可能是函数(truth table fiddle):

if ( xor( isEmptyString( firstStr ), isEmptyString( secondStr ) ) ) { ... }

然后你的具体例子是:

isEmptyString

或者,如果xor仅返回布尔值,而您不想使用通用if ( isEmptyString( firstStr ) ^ isEmptyString( secondStr ) ) { ... } 函数,则只需:

{{1}}

答案 9 :(得分:2)

假设您正在寻找BOOLEAN XOR,这是一个简单的实现。

function xor(expr1, expr2){
    return ((expr1 || expr2) && !(expr1 && expr2));
}

上述内容源于“独占分离”的定义{{one one,but not both}}。

答案 10 :(得分:1)

Javascript没有逻辑XOR运算符,因此您的构造似乎是合理的。如果它是数字,那么你可以使用^即按位XOR运算符。

欢呼声

答案 11 :(得分:1)

这是一个可以容纳两个到多个参数的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;
}

答案 12 :(得分:1)

我希望这将是最短最干净的

function xor(x,y){return true==(x!==y);}

这适用于任何类型

答案 13 :(得分:0)

@george,我喜欢你的功能,它有能力接收2个以上的操作数。我有一点点改进,以使其恢复得更快:

function xor() {
    for (var i=arguments.length-1, trueCount=0; i>=0; --i)
        if (arguments[i]) {
            if (trueCount)
                return false
            ++trueCount;
        }
    return trueCount & 1;
}

答案 14 :(得分:0)

你可以这样做:

Math.abs( isEmptyString(firstStr) - isEmptyString(secondStr) )

结果是XOR操作的结果。

答案 15 :(得分:0)

有几种方法,但三元方法(a?!b:b)似乎表现最佳。此外,如果您需要经常使用xor,设置Boolean.prototype.xor似乎是一个选项。

http://jsperf.com/xor-implementations

答案 16 :(得分:0)

试试这个: function xor(x,y) var result = x || y if (x === y) { result = false } return result }

答案 17 :(得分:0)

这是一个XOR函数,它接受可变数量的参数(包括两个)。论证只需要真实或虚假,而不是truefalse

function xor() {
    for (var i=arguments.length-1, trueCount=0; i>=0; --i)
        if (arguments[i])
            ++trueCount;
    return trueCount & 1;
}

在我的2007 MacBook上的Chrome上,它在14 ns内运行三个参数。奇怪的是,这个略有不同的版本需要2935 ns的三个参数:

function xorSlow() {
    for (var i=arguments.length-1, result=false; i>=0; --i)
        if (arguments[i])
            result ^= true;
    return result;
}