我正在尝试通过以下方式在JavaScript中实现XOR:

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

在JavaScript中有更好的方法吗?

谢谢。

有帮助吗?

解决方案

我假装您正在寻找逻辑XOR,因为JavaScript已经有一个(^):)

我通常使用一个简单的三元操作员(我使用的极少数时间之一):

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

编辑:

在@Jeff肉丸上工作 解决方案

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

您否定值以在布尔值中转换它们,然后应用位XOR操作员。也许它不像第一个解决方案那样可维护(或者我太习惯了第一个解决方案)

其他提示

正如其他人指出的那样,逻辑XOR与布尔人的不等式相同,因此您可以做到这一点:


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

您正在做一个布尔值的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

您可以使用位XOR操作员(^) 直接地:

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

因为布尔值 truefalse 值转换为 10 因为位运算符与32位整数一起工作。

该表达式也将返回 0 或者 1, ,并且该价值将被胁迫 if 陈述。

您应该意识到上述方法发生的类型强制,如果您要寻求良好的性能,我不建议您与位运算符合作,您也可以仅使用布尔逻辑来制作一个简单的功能操作员:

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


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

更容易的方法:

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

假设两个变量都是真正的布尔人,也就是说 1 或者 0.

  • 如果 x === y 你会得到一个偶数的数字,所以XOR将会 0.
  • 而如果 x !== y 那你会得到一个奇数,所以xor将会 1 :)

第二个选项,如果您注意到 x != y 评估为XOR,然后您要做的就是

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

它将再次评估为XOR。 (我更喜欢这一点)

当然,一个好主意是将其实施到一个函数中,但这只是您的选择。

希望这两种方法中的任何一种能帮助某人!我将此答案标记为社区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操作员。

您可以用类似的内容“模仿” XOR操作员的行为:

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

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

XOR只是表示“这两个布尔值有不同吗?”。所以:

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

!!S只是为了保证 != 操作员比较了两个真正的布尔值,因为可以想象 isEmptyString() 返回其他东西(例如 null 对于false或字符串本身为true)。

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

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

上面源自“独家分离”的定义{一个,但不是两者}。

由于布尔值 truefalse 转换为 10 分别在其上使用位运算符时,位于位XOR ^ 只要您的值是布尔值(JavaScript的“真实”值无法正常工作),只要您的值是逻辑XOR和BITWEESTONE,就可以将双重功能作为逻辑XOR和BITWEWSONE。否定很容易获得 ! 操作员。

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

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

还有很多其他形式 - 例如 !a ? !!b : !b - 但是这两种模式具有仅评估的优势 ab 一次一次(如果也不会“短路” a 是错误的,因此没有评估 b),同时使用三元 ?:, , 或者 ||, ,或者 && 操作员将双重评估或短路。

否定 ! 两个语句中的运营商都必须包括几个原因:它将所有“真实”值转换为布尔值(“” - > false,12-> true等),以便位于位运算符具有它可以使用的值,所以不平等 != 操作员仅比较每个表达的真实价值(a != b 如果 a 或者 b 是非平等,非空字符串等),因此每个评估都会返回布尔值结果,而不是第一个“真实”价值。

您可以通过添加双重否定来继续扩展这些表格(或例外, !!a ^ !!b, ,这仍然等同于XOR),但是在否定一部分表达时要小心。如果您在算术中的分布方面思考,这些形式乍一看似乎是“工作”(哪里 2(a + b) == 2a + 2b, 等等),但实际上从xor产生了不同的真理表(这些产生与逻辑NXOR相似的结果):

!( a ^ b )
!( !!a ^ !!b )
!!a == !!b

那么,XOR的一般形式可以是函数(真相表小提琴):

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

然后,您的具体示例将是:

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

或者如果 isEmptyString 仅返回布尔值,您不想要一般 xor 功能,简单:

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

JavaScript没有逻辑XOR操作员,因此您的构造似乎是合理的。如果是数字,那么您可以使用 ^ ie位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);}

这将适用于任何类型

这是一个XOR函数,该函数采用可变数量的参数(包括两个)。这些论点只需要真实或虚假,而不是 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 ns中进行了三个论点。奇怪的是,这个稍微不同的版本需要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 }

有几种方法,但是三元方法(a?!b:b)似乎表现最好。另外,如果您经常需要Xor事物,则设置boolean.prototype.xor似乎是一个选择。

http://jsperf.com/xor-implementations

您可以这样做:

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

结果是XOR操作的结果。

@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;
}
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top