So, it can get a bit confusing, but it's doable with xor
ing your values:
const xor = (a, b) => !a ^ !b;
const onlyOne = (a, b, c) => xor(xor(xor(a, b), c), a && b && c)
Or alternatively, since xor
is associative:
const onlyOne = (a, b, c) => !!a ^ !!b ^ !!c ^ (a && b && c)
Sure doingCan be optimized even further by removing some redundant computations:
const onlyOne = (a, b, c) => !a ^ !b ^ !c ^ !(a && b && c)
Doing a straight xor
on all 3 values leaves room for them all to be true, but then we just xor
that value in to get our results.
Also, the reason xor(a, b) != a ^ b
is to convert those values to boolean beforehand. It's nice that with booleans a ^ b === !a ^ !b
.
Edit: I didn't heed my own advice, with the last statement. Removed 2 !
(not) computations by removing the double negation to coerce into boolean.