DEV Community

Discussion on: JavaScript Interview Question #18: What's the sum of two booleans in JavaScript?

Collapse
 
lionelrowe profile image
lionel-rowe

You can use this property of booleans to implement an exclusive or:

const xor = (...bools) =>
    bools.reduce(
        (total, bool) => total + bool,
        0,
    ) === 1

xor(true, false) // true
xor(true, true, false) // false
xor(false, false) // false
xor(true) // true
Enter fullscreen mode Exit fullscreen mode
Collapse
 
coderslang profile image
Coderslang: Become a Software Engineer

That's clever. Thank you!

Collapse
 
willsmart profile image
willsmart

Or count things cleanly...

isEven = v => !(v & 1)

 // count the even numbers in an array
[1,2,3,4,5,6,7].reduce((acc, v)=> acc + isEven(v), 0) // <- 3
Enter fullscreen mode Exit fullscreen mode
Collapse
 
lionelrowe profile image
lionel-rowe • Edited

Now I think about it, filter with length would be simpler in both cases

const xor = (...bools) =>
    bools.filter(x => x).length === 1

const countEven = arr =>
    arr.filter(isEven).length
Enter fullscreen mode Exit fullscreen mode
Thread Thread
 
willsmart profile image
willsmart • Edited

A hell of a lot cleaner, in theory a bit slower too.
filter allocates, fills and returns an array, which we're then instantly throwing away after getting its length. reduce functions more like a for loop, iterating over each element and accumulating a sum.

That's in theory though. JS performance is fickle thing, and on perf.link it seems your filter method is both cleaner looking, and faster for arrays with fewer than 10000 items.
Perf.link link
Go figure! Good to know

What we really want is something like ruby's count, which only returns the filtered size...

isEven = -> (v) { (v&1)==0 }
[1,2,3,4,5,6,7].count(&isEven) # <- 3
Enter fullscreen mode Exit fullscreen mode

😎