find, some, every
Ask a question about a list without building a new one.
These three take the same kind of test function as filter, but they answer a question instead of building an array. find returns the first item that passes, or undefined. some returns true if any item passes. every returns true if all of them do.
They stop early. find and some quit at the first match, every quits at the first failure. On a big list that matters, and it reads better: the name says what you are asking.
includes is the primitive cousin: list.includes(value) for strings and numbers, no function needed. findIndex is find that returns the position, or -1.
Shape
const item = items.find((it) => test);
const any = items.some((it) => test);
const all = items.every((it) => test); Patterns
-
quiz.questions.find((q) => q.id === id) ?? nullFind, and turn the undefined into something deliberate.
-
results.some((r) => !r.answered)Any unanswered?
-
results.length > 0 && results.every((r) => r.correct)All correct, with the empty list handled on purpose.
-
results.findIndex((r) => !r.correct)Position of the first failure, or -1.
-
doc.shares.some((s) => s.email === email && s.permission === 'edit')Permission checks are some with a compound test.
Pitfalls
everyon an empty array returns true andsomereturns false. Mathematically right, often not what the product means. Guard with a length check when "all passed" should be false for nobody.findreturns the item,findIndexthe position,filterevery match. Pick the one whose return value you actually need.includesuses strict equality, so it works for primitives but never matches objects. For objects, usesome.
Exercises
Write the function, run it against the hidden cases. Cmd or Ctrl + Enter runs, Tab indents, Esc then Tab leaves the editor. 0 / 6 solved.
1. Find a question
Return the question with the given id from quiz.questions, or null when it is not there.
findQuestion({ questions: [{ id: "q1" }, { id: "q2" }] }, "q2") → { id: "q2" } 2. Any unanswered?
Return true when at least one result has answered: false.
hasUnanswered([{ answered: true }, { answered: false }]) → true 3. All passed
Return true only when every student has passed: true and there is at least one student.
allPassed([{ passed: true }, { passed: true }]) → true 4. First failure
Return the index of the first result with correct: false, or -1 if every result is correct.
firstFailure([{ correct: true }, { correct: false }, { correct: false }]) → 1 5. Can edit?
A document has an owner email and a shares list of { email, permission }. Return true when the given email is the owner or has a share with permission edit.
canEdit(
{
owner: "r@x.com",
shares: [
{ email: "s@x.com", permission: "view" },
{ email: "e@x.com", permission: "edit" }
]
},
"r@x.com"
) → true 6. Any of these topics
Return the questions whose topics list contains at least one of the given wanted topics, in input order.
questionsInAnyTopic(
[
{ id: "q1", topics: ["vitals"] },
{ id: "q2", topics: ["safety", "vitals"] },
{ id: "q3", topics: [] },
{ id: "q4", topics: ["meds"] }
],
["vitals", "meds"]
) → [
{ id: "q1", topics: ["vitals"] },
{ id: "q2", topics: ["safety", "vitals"] },
{ id: "q4", topics: ["meds"] }
] Order a copy of the list with a comparator you control.