Array Search Methods
find, findIndex, some, every, and includes all scan an array and can stop as soon as they know the answer.
Loading visual…
Definition
`find` and `findIndex` both walk an array from the start, calling a callback on each element until the callback returns a truthy value. `find` returns the matching element itself, or `undefined` if nothing matched; `findIndex` returns the matching index instead, or `-1` if nothing matched. Both stop scanning the moment a match is found, so any elements after it are never checked. `some` and `every` answer yes/no questions about an array and both short-circuit too. `some` returns `true` the moment any element makes the callback return truthy, and only returns `false` after checking every element and finding none; `every` returns `false` the moment any element makes the callback return falsy, and only returns `true` after every element passes. `includes` checks whether an array directly contains a given value (not a callback result), and unlike the older `indexOf`, `includes` correctly reports `true` for `NaN`, because it uses a comparison that treats `NaN` as equal to itself.
Examples
const users = [{ id: 1 }, { id: 2 }, { id: 3 }];
users.find(u => u.id === 2); // { id: 2 }
users.findIndex(u => u.id === 2); // 1
users.find(u => u.id === 99); // undefinedfind returns the matching object itself, findIndex returns its position, and both return the "not found" value (undefined or -1) if nothing matches.
const scores = [72, 88, 91, 60];
scores.every(s => s >= 60); // true, every score passes
scores.some(s => s >= 90); // true, stops at 91
scores.every(s => s >= 70); // false, stops at 60every keeps checking until it finds one score below 70 and stops there; some stops as soon as it finds one score of 90 or higher.
[1, 2, NaN].includes(NaN); // true
[1, 2, NaN].indexOf(NaN); // -1includes finds NaN correctly, but indexOf cannot, because indexOf compares with === and NaN === NaN is false.
Common mistakes
- Confusing find, which returns the matching value, with findIndex, which returns the matching position.
- Assuming every returns false for an empty array; it actually returns true, since there is no element to fail the check.
- Reaching for indexOf to search for NaN, which never finds it, instead of includes, which does.
Key takeaways
- find and findIndex stop scanning as soon as the callback returns true for one element.
- some short-circuits on the first truthy result, every short-circuits on the first falsy result.
- includes checks for a value directly and, unlike indexOf, correctly matches NaN.
[3, 7, 12, 5].find(x => x > 10)
Where you see this
- Looking up a single record by id in a small in-memory list with find, without writing a manual loop.
- Validating that every field in a form passes its rule with every, stopping at the first failure.
- Checking whether a shopping cart contains at least one out-of-stock item with some.
- Testing membership of a value, including NaN, with includes instead of a manual comparison loop.