find, some and every
filter returns every matching element, but often only the first one is needed, or the answer to "is there one at all". Running the whole belt for that is pointless.
Back to the conveyor. forEach had no stop button, but the methods of this lesson have one. The worker looks for the right box on the belt and stops the belt as soon as the answer is known. The worker no longer looks at the remaining boxes.
const ages = [12, 17, 21, 30];
console.log(ages.find((a) => a >= 18)); // 21
console.log(ages.findIndex((a) => a >= 18)); // 2
console.log(ages.find((a) => a > 100)); // undefined
console.log(ages.findIndex((a) => a > 100)); // -1Let's see what each line prints:
findlooks for the first age from18up and finds21.findIndexwith the same condition returns the index of that element,2.- There is no age above
100, sofindreturnsundefined. - In the same case
findIndexreturns-1.
find and findIndex
Both methods look for the first element that meets a condition. They differ in what they return.
find
find calls the callback for the elements in order and returns the first element for which the callback returned a truthy value. It does not check the remaining elements. If no element matches, find returns undefined.
filter with the same condition would return the array [21, 30], even when only the first element is needed.
findIndex
findIndex searches the same way but returns the index of the element it found. If nothing is found, the result is -1, as with indexOf.
The difference is that indexOf looks for an equal value, while findIndex looks for an element that meets a condition. The index is useful when the element found must be replaced or cut out with splice.
some and every
The methods some and every answer with a boolean, that is true or false. The includes method also answers "is there one or not", but it looks for an equal value. It cannot check a condition like a > 20.
console.log(ages.some((a) => a < 14)); // true
console.log(ages.every((a) => a >= 18)); // false
console.log([].some((a) => a > 0), [].every((a) => a > 0)); // false truesome and every usually stand in an if condition. The condition if (ages.every((a) => a >= 18)) lets through only a list where everyone is an adult.
some
some returns true if the condition holds for at least one element. In the example there is an age below 14, namely 12, so the result is true.
every
every returns true only if the condition holds for all the elements. In the example 12 and 17 are below 18, so the result is false.
Stopping and the empty array
some stops at the first true, every at the first false. An empty array has neither matching nor failing elements, so some gives false and every gives true.
The true from every on an empty array surprises many people, and interviewers like to ask about it. Remember it this way: every looks for an element that breaks the condition, and an empty array has none.
Common mistake
The result of find is used without checking whether anything was found:
const names = ["Ann", "Bob"];
const found = names.find((name) => name.startsWith("Z"));
console.log(found.toUpperCase()); // ✗TypeError: Cannot read properties of undefined (reading 'toUpperCase')The array has no name starting with Z, so found is undefined, and undefined has no methods. Before working with the result, compare it with undefined: if (found !== undefined).
if (found) does not fit here: a found 0 or empty string is falsy, and the if decides nothing was found. If only the answer "is there one or not" is needed, use some.
Key points
findreturns the first matching element orundefined,findIndexits index or-1.someanswers whether at least one element matches,everywhether all of them do.- All four methods stop as soon as the answer is known.
- For an empty array
somegivesfalseandeverygivestrue.
Subscribe to take the course
The course is free. Sign in with Telegram and subscribe to the channel to open every lesson.