Asking questions of an array
Three more methods take an arrow that answers true or false, but instead of building arrays they answer questions:
find(test)→ the first item that passes, orundefinedif none do.some(test)→trueif at least one item passes (Python'sany).every(test)→trueif all items pass (Python'sall).
They shine on arrays of objects, which is how real data usually arrives:
const users = [ { name: "Ada", age: 36 }, { name: "Alan", age: 41 } ]; const alan = users.find(u => u.name === "Alan"); // the whole object
find hands you the object itself, so alan.age is 41. For simple membership checks on plain values, includes from lesson 4-2 is still the shortest tool.
One search and three group questions
find returns the whole matching object, while some and every answer yes-or-no questions about the group as a whole.
const users = [ { name: "Ada", age: 36 }, { name: "Alan", age: 41 }, { name: "Grace", age: 85 } ]; const alan = users.find(u => u.name === "Alan"); console.log(alan.age); console.log(users.some(u => u.age > 80)); console.log(users.every(u => u.age >= 18)); console.log(users.some(u => u.name === "Linus"));
Output
41 true true false
find handed back the entire Alan object, not his position and not his name, which is why alan.age works directly on the result.
The three boolean lines each read as a sentence about the array. At least one user is over 80, since Grace is 85. Every user is an adult, since the youngest is 36. And no user is named Linus, so some reports false. Both methods stop early when they can, so some quits at its first success and every quits at its first failure.
Finding a record and validating a whole list
Two different questions about one inventory. The first locates a specific record, and the second checks a rule against every record at once.
const items = [ { name: "pen", qty: 12, price: 1.5 }, { name: "ink", qty: 0, price: 9 }, { name: "pad", qty: 4, price: 3 } ]; const out = items.find(i => i.qty === 0); console.log(out.name); console.log(items.every(i => i.price > 0));
Output
ink
trueThe find call tests i.qty === 0 with strict equality, which matters for a quantity check, since filter-style loose comparisons would also treat an empty string or false as zero. Once the ink record comes back, out.name reaches into it like any other object.
The every call is a data-quality check of the kind that belongs at the edges of a program, right after data arrives. It answers true here because all three prices are above zero, and a single bad record would flip it to false and be worth investigating.
When find matches nothing
users.find(u => u.age > 200) matches nobody, and the call returns undefined.
That return value is the reason careful code checks the result before using it. Writing users.find(...).name on a miss becomes undefined.name, which throws TypeError: Cannot read properties of undefined. The usual shapes for guarding it are an if around the use, or optional chaining from lesson 5-2 as found?.name, which quietly gives undefined instead of crashing.
It also helps to keep the empty results of these methods straight, because they are not the same value.
| Method | Result when nothing matches |
|---|---|
find | undefined |
filter | [], an empty array |
some | false |
every | true, since no item broke the rule |
That last row surprises people.
everyon an empty array istrue, because the method reports whether any item failed, and an empty array has nothing that could fail.