ESC

Type to search the knowledge base.

Array find, some, every, includes

Short-circuiting array predicates: find, findIndex, some, every, and includes — when to use each and common interview traps.

beginner3 min read
  • javascript
  • arrays
  • find
  • some
  • every

You do not need filter when you only care about one match or a yes/no answer. find, some, every, and includes short-circuit: they stop as soon as the answer is known. That is both clearer and cheaper on large lists.

Cheat sheet

Method Returns Stops when
arr.includes(x) boolean first SameValueZero match
arr.some(fn) boolean first truthy predicate
arr.every(fn) boolean first falsy predicate
arr.find(fn) element or undefined first truthy predicate
arr.findIndex(fn) index or -1 first truthy predicate
arr.findLast(fn) element or undefined last match (ES2023)
const users = [
  { id: 1, role: 'user', active: true },
  { id: 2, role: 'admin', active: false },
  { id: 3, role: 'admin', active: true },
];

users.find((u) => u.role === 'admin');
// { id: 2, role: 'admin', active: false }

users.some((u) => u.role === 'admin' && u.active); // true
users.every((u) => u.active); // false
users.includes(users[0]); // true — reference equality for objects
[1, 2, NaN].includes(NaN); // true — SameValueZero

includes vs some vs find

  • includes — fixed value, SameValueZero (so NaN works; objects only by reference).
  • some — any condition. “Is there an admin?”
  • find — same condition, but you need the element.
  • every — validation: “all items pass?” Empty array: every is true, some is false (vacuous truth).
[].every(() => false); // true
[].some(() => true);   // false

const ids = [10, 20, 30];
ids.includes(20);                    // true
ids.some((id) => id > 25);           // true
ids.find((id) => id > 25);           // 30
ids.findIndex((id) => id > 25);      // 2

Sparse arrays and holes

Callbacks skip empty slots. includes treats holes as undefined:

const sparse = ['a', , 'c'];
sparse.some((x) => x === undefined); // false — hole skipped
sparse.includes(undefined);          // true — hole counts

Real UI patterns

// permission gate
function canPublish(user) {
  return user.permissions.some((p) => p === 'publish' || p === 'admin');
}

// form validation
function allRequiredFilled(fields) {
  return fields.every((f) => f.value.trim().length > 0);
}

// pick first error message
function firstError(fields) {
  return fields.find((f) => f.error)?.error ?? null;
}

Avoid filter(...)[0] when find is enough — you allocate a whole array for one element.

Footguns

  1. Object identity: [{a:1}].includes({a:1}) is false. Use some with a field compare.
  2. Truthy traps in find: find(x => x) skips 0, '', false. Be explicit.
  3. Mutating during iteration — don’t; results are unspecified territory.
  4. indexOf vs includes: prefer includes for existence; indexOf when you need the index of a primitive (or use findIndex).
// wrong for “is this user in the list?”
selectedUsers.includes(currentUserFromApi); // new object each fetch

// right
selectedUsers.some((u) => u.id === currentUserFromApi.id);

Interview answer

“includes checks value presence with SameValueZero. some/every are boolean predicates with short-circuiting; empty arrays make every true and some false. find/findIndex return the first match or undefined/-1. I use find instead of filter-then-[0], and some with a key compare for objects instead of includes.”

Further reading

Related guides