views:

599

answers:

8

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.

+3  A: 

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;
}
froadie
lol. 4 secs difference :)
Roberto Aloi
Could you please provide answers here, rather than pushing users off of the site to get what they're looking for?
Jonathan Sampson
@Jonathan Sampson - I could if you think that would be helpful. But what exactly would be the reason to copy the code into the post? The resource already exists
froadie
@foadie: Because Stack Overflow is for *answers*, not *links to answers*. If your link broke tomorrow, your answer would lose **all** value.
Jonathan Sampson
@Jonathan Sampson - criticism taken
froadie
@froadie: Thanks. Much better :)
Jonathan Sampson
+1  A: 

You might be interested in this.

Roberto Aloi
Could you please provide answers here, rather than pushing users off of the site to get what they're looking for?
Jonathan Sampson
Are you asking us to copy and paste an already existing answer in StackOverflow so the users stay on the website? O_o
Roberto Aloi
@Roberto: Copy and paste? No. Why don't you explain the same (or similar) solutions here for the good of those who come across this question. If your link broke tomorrow, your answer would serve no purpose.
Jonathan Sampson
Good article. The best answer is on the bottom of the page. Why not just post that with a brief explanation?
simon
+3  A: 

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

Jeff Meatball Yang
+1 ... This is how I was always taught to do XOR.
Robusto
thinking on your answer... why not !isEmptyString(firstStr) ^ !isEmptyString(secondStr)
Eineki
+1  A: 

Hi

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

Andriyev
Booleans coerce to 1 and 0 as you would expect, so you can use the XOR operator with booleans.
Mike Samuel
+2  A: 

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)

Eineki
Thanks, I'll use this suggestion.
amoran
I didn't catch the negation in the OP's logic - good one!
Jeff Meatball Yang
Just another thought: I like the use of the bitwise XOR because I think the ternary operator is harder for someone else to read/understand as an XOR.
Jeff Meatball Yang
A: 

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))) {
  // ...
}
CMS
+1  A: 

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

Sean
+3  A: 

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