简体   繁体   English

无论如何在javascript中实现XOR

[英]Is there anyway to implement XOR in javascript

I'm trying to implement XOR in javascript in the following way: 我试图通过以下方式在javascript中实现XOR:

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

Is there a better way to do this in javascript? 有没有更好的方法在JavaScript中执行此操作?

Thanks. 谢谢。

As others have pointed out, logical XOR is the same as not-equal for booleans, so you can do this: 正如其他人所指出的那样,逻辑XOR对于布尔值来说是不相等的,所以你可以这样做:


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

I pretend that you are looking for a logical XOR, as javascript already has a bitwise one (^) :) 我假装你正在寻找一个逻辑XOR,因为javascript已经有一个按位(^):)

I usually use a simple ternary operator (one of the rare times I use one): 我通常使用一个简单的三元运算符(我很少使用其中一个):

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

Edit: 编辑:

working on the @Jeff Meatball Yang solution 致力于@Jeff Meatball Yang 解决方案

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

you negate the values in order to transform them in booleans and then apply the bitwise xor operator. 你否定了值以便在布尔值中转换它们然后应用按位xor运算符。 Maybe it is not so maintainable as the first solution (or maybe I'm too accustomed to the first one) 也许它不像第一个解决方案那么可维护(或者我可能已经习惯了第一个解决方案)

You are doing an XOR of boolean values which is easy to model into a bitwise XOR (which Javascript has): 你正在做一个布尔值的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 http://www.howtocreate.co.uk/xor.html

You could use the bitwise XOR operator ( ^ ) directly: 您可以直接使用按位XOR运算符( ^ ):

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

It will work for your example since the boolean true and false values are converted into 1 and 0 because the bitwise operators work with 32-bit integers. 它将适用于您的示例,因为布尔值truefalse值被转换为10因为按位运算符使用32位整数。

That expression will return also either 0 or 1 , and that value will be coerced back to Boolean by the if statement. 该表达式也将返回01 ,并且该值将由if语句强制回布尔值。

You should be aware of the type coercion that occurs with the above approach, if you are looking for good performance, I wouldn't recommend you to work with the bitwise operators, you could also make a simple function to do it using only Boolean logical operators: 您应该知道上述方法发生的类型强制,如果您正在寻找良好的性能,我不建议您使用按位运算符,您也可以使用仅逻辑逻辑来创建一个简单的函数运营商:

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


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

Easier one method: 一种方法更简单:

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

assuming of course that both variables are true booleans, that is, 1 or 0 . 当然假设两个变量都是真正的布尔值,即10

  • If x === y you'll get an even number, so XOR will be 0 . 如果x === y你会得到一个偶数,所以XOR将为0
  • And if x !== y then you'll get an odd number, so XOR will be 1 :) 如果x !== y那么你会得到一个奇数,所以XOR将是1 :)

A second option, if you notice that x != y evaluates as a XOR, then all you must do is 第二种选择,如果您注意到x != y计算结果是异或,那么您必须做的就是

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

Which will just evaluate, again, as a XOR. 这将再次评估为异或。 (I like this much better) (我更喜欢这个)

Of course, a nice idea would be to implement this into a function, but it's your choice only. 当然,一个好主意是将它实现为一个函数,但它只是你的选择。

Hope any of the two methods help someone! 希望这两种方法中的任何一种都能帮到别 I mark this answer as community wiki, so it can be improved. 我将此答案标记为社区维基,因此可以进行改进。

Checkout this explanation of different implementations of XOR in javascript. 在javascript中查看XOR的不同实现的这种解释。

Just to summarize a few of them right here: 只是在这里总结一些:

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

Quoting from this article: 从引用文章:

Unfortunately, JavaScript does not have a logical XOR operator. 不幸的是,JavaScript没有逻辑XOR运算符。

You can "emulate" the behaviour of the XOR operator with something like: 您可以通过以下方式“模拟”XOR运算符的行为:

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

The linked article discusses a couple of alternative approaches. 链接的文章讨论了几种替代方法。

Assuming you are looking for the BOOLEAN XOR, here is a simple implementation. 假设您正在寻找BOOLEAN XOR,这是一个简单的实现。

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

The above derives from the definition of an "exclusive disjunction" {either one, but not both}. 以上来源于“独占分离”的定义{任一个,但不是两个}。

Since the boolean values true and false are converted to 1 and 0 respectively when using bitwise operators on them, the bitwise-XOR ^ can do double-duty as a logical XOR as well as a bitwiseone, so long as your values are boolean values (Javascript's "truthy" values wont work). 由于布尔值truefalse在使用按位运算符时分别转换为10 ,因此只要值为布尔值,bitwise-XOR ^就可以作为逻辑XOR和bitwiseone执行双重任务( Javascript的“truthy”值不会起作用)。 This is easy to acheive with the negation ! 否定就容易实现这一点! operator. 运营商。

a XOR b is logially equivalent to the following (short) list of expressions: a XOR b在逻辑上等同于以下(短)表达式列表:

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

There are plenty of other forms possible - such as !a ? !!b : !b 还有很多其他形式 - 例如!a ? !!b : !b !a ? !!b : !b - but these two patterns have the advantage of only evaluating a and b once each (and will not "short-circuit" too if a is false and thus not evaluate b ), while forms using ternary ?: , OR || !a ? !!b : !b - 但是这两种模式的优点是只评估ab一次(并且如果a是假的则不会“短路”,因此不评估b ),而使用三元的形式?: ,或者|| , or AND && operators will either double-evaluate or short-circuit. 或AND &&运算符将进行双重评估或短路。

The negation ! 否定! operators in both statements is important to include for a couple reasons: it converts all "truthy" values into boolean values ( "" -> false, 12 -> true, etc.) so that the bitwise operator has values it can work with, so the inequality != operator only compares each expression's truth value ( a != b would not work properly if a or b were non-equal, non-empty strings, etc.), and so that each evaluation returns a boolean value result instead of the first "truthy" value. 两个语句中的运算符很重要,包括几个原因:它将所有“truthy”值转换为布尔值(“” - > false,12 - > true等),以便按位运算符具有可以使用的值,所以不等式!=运算符只比较每个表达式的真值(如果ab不相等,非空字符串等,则a != b将无法正常工作),以便每个评估返回一个布尔值结果第一个“真实”的价值。

You can keep expanding on these forms by adding double negations (or the exception, !!a ^ !!b , which is still equivalent to XOR), but be careful when negating just part of the expression. 您可以通过添加双重否定(或异常, !!a ^ !!b ,仍然等效于XOR)继续扩展这些表单,但在否定表达式的一部分时要小心。 These forms may seem at first glance to "work" if you're thinking in terms of distribution in arithmatic (where 2(a + b) == 2a + 2b , etc.), but in fact produce different truth tables from XOR ( these produce similar results to logical NXOR ): 如果你考虑算术中的分布(其中2(a + b) == 2a + 2b等),这些形式似乎乍一看“工作”,但实际上从XOR产生不同的真值表( 这些产生与逻辑NXOR类似的结果 ):

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

The general form for XOR, then, could be the function ( truth table fiddle ): 那么,XOR的一般形式可能是函数( 真值表小提琴 ):

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

And your specific example would then be: 然后你的具体例子是:

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

Or if isEmptyString returns only boolean values and you don't want a general xor function, simply: 或者,如果isEmptyString仅返回布尔值,并且您不需要通用的xor函数,则只需:

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

XOR just means "are these two boolean values different?". XOR只是意味着“这两个布尔值是不同的吗?”。 Therefore: 因此:

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

The !! !! s are just to guarantee that the != operator compares two genuine boolean values, since conceivably isEmptyString() returns something else (like null for false, or the string itself for true). s只是为了保证!=运算符比较两个真正的布尔值,因为可以想象isEmptyString()返回其他内容(如nullnull ,或者字符串本身为true)。

I hope this will be the shortest and cleanest one 我希望这将是最短最干净的

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

This will work for any type 这适用于任何类型

Javascript does not have a logical XOR operator, so your construct seems plausible. Javascript没有逻辑XOR运算符,因此您的构造似乎是合理的。 Had it been numbers then you could have used ^ ie bitwise XOR operator. 如果它是数字,那么你可以使用^即按位XOR运算符。

cheers 干杯

here's an XOR that can accommodate from two to many arguments 这是一个可以容纳两个到多个参数的XOR

function XOR() {
    for (var i = 1; i < arguments.length; i++) 
        if ( arguments[0] != arguments[i] ) 
            return false; 
    return true; 
}

Example of use: 使用示例:

if ( XOR( isEmptyString(firstStr), isEmptyString(secondStr) ) ) {
    alert(SOME_VALIDATION_MSG);
    return;
}

Here is an XOR function that takes a variable number of arguments (including two). 这是一个XOR函数,它接受可变数量的参数(包括两个)。 The arguments only need to be truthy or falsy, not true or false . 争论只需要truefalse ,不是truefalse

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

On Chrome on my 2007 MacBook, it runs in 14 ns for three arguments. 在我的2007 MacBook上的Chrome上,它在14 ns内运行三个参数。 Oddly, this slightly different version takes 2935 ns for three arguments: 奇怪的是,这个略有不同的版本需要2935 ns的三个参数:

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

Try this: 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 } function xor(x,y) var result = x || y if (x === y) { result = false } return result }

There's a few methods, but the ternary method (a ? !b : b) appears to perform best. 有几种方法,但三元方法(a?!b:b)似乎表现最佳。 Also, setting Boolean.prototype.xor appears to be an option if you need to xor things often. 此外,如果您需要经常使用xor,设置Boolean.prototype.xor似乎是一个选项。

http://jsperf.com/xor-implementations http://jsperf.com/xor-implementations

You could do this: 你可以这样做:

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

The result of that is the result of a XOR operation. 结果是XOR运算的结果。

@george, I like your function for its capability to take in more than 2 operands. @george,我喜欢你的功能,因为它能够接收2个以上的操作数。 I have a slight improvement to make it return faster: 我有一点点改进,使它恢复得更快:

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 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM