I\'m trying to implement XOR in javascript in the following way:
// XOR validation
if ((isEmptyString(firstStr) && !isEmptyString(secondStr)) |
You could do this:
Math.abs( isEmptyString(firstStr) - isEmptyString(secondStr) )
The result of that is the result of a XOR operation.
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
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}.
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 ) ) { ... }
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;
}
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