← All concepts
Working With Arrays

Array Search Methods

find, findIndex, some, every, and includes all scan an array and can stop as soon as they know the answer.

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); // undefined

find 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 60

every 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); // -1

includes 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.
Check your understanding

[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.

Practice this

Further reading

Previous
Sorting Arrays
Next
Timers and Scheduling