We can all pretty intuitively understand how .some()
and .every()
predicate
expressions on lists work.
Let's define a list of Simpsons:
const simpsons = [ { name: 'Homer', age: 39 }, { name: 'Marge', age: 37 }, { name: 'Bart', age: 13 }, { name: 'Lisa', age: 11 }, { name: 'Maggie', age: 4 }, ];
And a predicate to tell if someone is an adult:
function isAdult(simpson) { return simpson.age >= 18; }
Then, these statements are pretty obvious:
simpsons.some(isAdult); // => true, because Homer and Marge are adults simpsons.every(isAdult); // => false, because not everyone is an adult
But it's not immediately obvious why these are the defaults for an empty list:
[].some(isAdult); // => false [].every(isAdult); // => true
Every person in the empty list is an adult? That sounds weird when you say it.
It doesn't matter what predicate you pass in here though, it will not affect the result. In other words, every person in the empty list is also NOT an adult 😉
One intuition that can help with this, is to think of .some()
and .every()
as chains of logical "or" and "and" expressions:
// .some() is a chain of "or"s isAdult(homer) || isAdult(marge) || isAdult(bart) || ... // .every() is a chain of "and"s isAdult(homer) && isAdult(marge) && isAdult(bart) && ...
You can tack a constant to the beginning of these chains in a way that keeps them logically equivalent:
false || isAdult(homer) || isAdult(marge) || isAdult(bart) || ... true && isAdult(homer) && isAdult(marge) && isAdult(bart) && ...
And that's why those are the defaults for the empty list!