1

I was looking to XOR three boolean variables. Only one can be true, and one must be true:

function isValid(a, b, c) { return a !== b !== c; }

var one = false;
var two = false;
var three = true;

console.log(isValid(one, two, three)); // should be true  

one = true;
console.log(isValid(one, two, three)); // should be false

This solution seems to work, but my question is... why? Shouldn't it fail if all values are false?

var one = false;
var two = false;
var three = false;
console.log(isValid(one, two, three)); // should be true, but it is false

Additionally, all variables being true, returns true when it should return false.

var one = true;
var two = true;
var three = true;
console.log(isValid(one, two, three)); // should be false, but it's true

My thought is that it executes thusly:

a    !== b?  TRUE
TRUE !== c?  TRUE

Clearly that isn't how it works, so how does it work?

7
  • 3
    JavaScript is not like Python. a !== b !== c means (a !== b) !== c, and (a !== b) yields a boolean value, and that value is what's compared to c. Commented Aug 29, 2019 at 16:45
  • If they're all true, it outputs true as well Commented Aug 29, 2019 at 16:46
  • a !== b this is false, since both elements have the value false. Then you get false !== c, which is also false, since c has the value false. So your solution does not do what you think it does. Commented Aug 29, 2019 at 16:47
  • 1
    In the same vein, if all are true, you get ( true !== true ), which is false. And then false !== true, which is true. Commented Aug 29, 2019 at 16:48
  • 1
    Bottom line is this: you want a !== b && a !== c && b !== c Commented Aug 29, 2019 at 16:52

2 Answers 2

6

This solution seems to work, but my question is... why?

It doesn't work for what you described (only one can be true, and one must be true); it fails in the true, true, true case:

function isValid(a, b, c) { return a !== b !== c; }

console.log(isValid(true, true, true)); // true, should be false

I should note that I don't think your rule is quite the same as XOR, since true XOR true XOR true is true (because true XOR true is false, and false XOR true is true).

a !== b !== c is evaluated like this:

  • a !== b is evaluated and yields a boolean result, either true if the condition is true or false if it's false. Call that r. In the true, true, true case, true !== true is false so r = false.
  • r !== c is evaluated and yields its boolean result. In the true, true, true case, false !== true is true.

As you can see from the above, it works in almost all XOR cases, but not when all the inputs are true. It also doesn't work for other examples. Probably the most common error people make is trying to see if a, b, and c all have the same value:

if (a === b === c) // WRONG (almost always)

Since that's ((a === b) === c) which is (some_boolean === c), it's almost always wrong (for instance, if a, b, and c contain anything but boolean values).

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks. I soon discovered all true got me the error. I came up with a solution, but I feel there is a better one: stackoverflow.com/questions/57714740/…
@Jeff - Actually...now I think about it, true XOR true XOR true should be true, because true XOR true is false, and false XOR true is true. It just happens that for this particular operation, a !== b !== c produces the expected result for XOR (but not for what you said you wanted). But you can't generalize that... :-)
3

Since the operator are of same precedence so the Associativity decides how this is going to be evaluate Operator precedence

function isValid(a, b, c) { return a !== b !== c; }

var one = false;
var two = false;
var three = true;

You can understand it step by step

   a !== b   -> this return `false` as false !== false 

so now the condition is

 false !== c  -> this return `true` as false !== true 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.