Is there anyway to implement XOR in javascript

雨燕双飞 提交于 2020-04-29 05:53:23

问题


I'm trying to implement XOR in javascript in the following way:

   // 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?

Thanks.


回答1:


I pretend that you are looking for a logical XOR, as javascript already has a bitwise one (^) :)

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

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. Maybe it is not so maintainable as the first solution (or maybe I'm too accustomed to the first one)




回答2:


As others have pointed out, logical XOR is the same as not-equal for booleans, so you can do this:


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



回答3:


You are doing an XOR of boolean values which is easy to model into a bitwise XOR (which Javascript has):

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

if(a ^ b) { ... }

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




回答4:


You could use the bitwise XOR operator (^) directly:

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.

That expression will return also either 0 or 1, and that value will be coerced back to Boolean by the if statement.

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))) {
  // ...
}



回答5:


Easier one method:

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

assuming of course that both variables are true booleans, that is, 1 or 0.

  • If x === y you'll get an even number, so XOR will be 0.
  • And if x !== y then you'll get an odd number, so XOR will be 1 :)

A second option, if you notice that x != y evaluates as a XOR, then all you must do is

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.




回答6:


Checkout this explanation of different implementations of XOR in javascript.

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



回答7:


Quoting from this article:

Unfortunately, JavaScript does not have a logical XOR operator.

You can "emulate" the behaviour of the XOR operator with something like:

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

The linked article discusses a couple of alternative approaches.




回答8:


XOR just means "are these two boolean values different?". 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).




回答9:


Assuming you are looking for the BOOLEAN XOR, here is a simple implementation.

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

The above derives from the definition of an "exclusive disjunction" {either one, but not both}.




回答10:


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). This is easy to acheive with the negation ! operator.

a XOR b is logially equivalent to the following (short) list of expressions:

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

There are plenty of other forms possible - such as !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 ||, or AND && operators will either double-evaluate or short-circuit.

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.

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. 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):

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

The general form for XOR, then, could be the function (truth table fiddle):

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:

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



回答11:


Javascript does not have a logical XOR operator, so your construct seems plausible. Had it been numbers then you could have used ^ i.e. bitwise XOR operator.

cheers




回答12:


here's an XOR that can accommodate from two to many arguments

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



回答13:


I hope this will be the shortest and cleanest one

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

This will work for any type




回答14:


Here is an XOR function that takes a variable number of arguments (including two). The arguments only need to be truthy or falsy, not true or false.

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. Oddly, this slightly different version takes 2935 ns for three arguments:

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



回答15:


Try this: function xor(x,y) var result = x || y if (x === y) { result = false } return result }




回答16:


There's a few methods, but the ternary method (a ? !b : b) appears to perform best. Also, setting Boolean.prototype.xor appears to be an option if you need to xor things often.

http://jsperf.com/xor-implementations




回答17:


You could do this:

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

The result of that is the result of a XOR operation.




回答18:


@george, I like your function for its capability to take in more than 2 operands. 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;
}


来源:https://stackoverflow.com/questions/2335979/is-there-anyway-to-implement-xor-in-javascript

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!