Knowledge Base/concepts/When to Use some and every in JavaScript

When to Use some and every in JavaScript

Use some and every in JavaScript when the answer should be a boolean, not a smaller array. some asks, "does at least one item pass?" every asks, "do all items pass?" They are not shorter versions of filter. They express a different kind of question, and that difference matters most in validation, permissions, alerts, and status summaries.

The bug usually starts when code builds a list just to check whether the list has anything in it.

The short rule

Use some when one match is enough:

const hasExpiredSession = sessions.some((session) => session.expiresAt <= now);

Use every when one failure should fail the whole check:

const allFieldsFilled = requiredFields.every((field) => field.value.trim());

Both methods return booleans:

NeedMethodEmpty array result
At least one item passessomefalse
All items passeverytrue

That empty-array behavior is logical, but it can be surprising. We will come back to it, because it is where a lot of real validation bugs hide.

The naive filter check

This works:

const urgentTasks = tasks.filter((task) => task.urgent);
const hasUrgentTask = urgentTasks.length > 0;

But it builds a list when the program only needs yes or no. some says the same thing directly:

const hasUrgentTask = tasks.some((task) => task.urgent);

The second version gives the reader the right mental model. We are not going to render every urgent task. We only need to know whether an urgent task exists.

The same applies to "none" checks. Instead of filtering and checking for zero matches:

const blockedChecks = checks.filter((check) => check.status === "blocked");
const hasNoBlockers = blockedChecks.length === 0;

Use some, then negate the boolean:

const hasNoBlockers = !checks.some((check) => check.status === "blocked");

That reads as "there is not any blocked check."

some answers any-match questions

some returns true as soon as one callback result is truthy.

const payments = [
  { id: "p1", status: "paid" },
  { id: "p2", status: "failed" },
  { id: "p3", status: "pending" },
];

const needsAttention = payments.some((payment) => payment.status === "failed");

console.log(needsAttention); // true

Use some for questions like:

  • Does this list contain a risky record?
  • Should this warning appear?
  • Is any required dependency missing?
  • Did at least one check fail?
  • Can any available option handle this input?

Those are existence questions. One match is enough.

every answers all-match questions

every returns true only if every callback result is truthy.

const fields = [
  { name: "email", value: "ada@example.com" },
  { name: "password", value: "correct horse" },
];

const canSubmit = fields.every((field) => field.value.trim().length > 0);

console.log(canSubmit); // true

Use every for questions like:

  • Did all required fields pass validation?
  • Does every selected row have the same status?
  • Are all permissions enabled?
  • Did every migration step finish?
  • Is every item safe to publish?

These are coverage questions. One failing item should make the answer false.

The empty-array trap with every

every returns true for an empty array.

console.log([].every((item) => item.approved));
// true

That looks strange until you think about the rule: every returns false only when it finds an item that fails. An empty array has no failing item.

That behavior is useful in math and logic. It can be wrong for business rules:

function canLaunchRelease(approvals) {
  return approvals.every((approval) => approval.status === "approved");
}

console.log(canLaunchRelease([]));
// true

For a release flow, "no approvals exist" probably should not mean "all approvals passed." Add the non-empty requirement explicitly:

function canLaunchRelease(approvals) {
  return (
    approvals.length > 0 &&
    approvals.every((approval) => approval.status === "approved")
  );
}

console.log(canLaunchRelease([]));
// false

This is not a flaw in every. It is a reminder that method semantics and product rules are different things. Code has to say both.

some and every can stop early

Like find, both methods short-circuit.

some stops when it finds the first passing item:

let checkedForBlocker = 0;

const hasBlocker = checks.some((check) => {
  checkedForBlocker += 1;
  return check.status === "blocked";
});

every stops when it finds the first failing item:

let checkedForApproval = 0;

const allApproved = checks.every((check) => {
  checkedForApproval += 1;
  return check.status === "approved";
});

That short-circuiting matters when the callback is expensive, but the bigger win is clarity. some and every tell the next reader when the search is allowed to stop.

Use predicates, not clever return values

The callback for some and every should be a predicate: one item in, boolean-style answer out.

This is fine:

const allUsersHaveEmail = users.every((user) => user.email.trim().length > 0);

This works because non-empty strings are truthy, but it is less clear:

const allUsersHaveEmail = users.every((user) => user.email.trim());

Prefer the explicit comparison when the rule matters. It prevents readers from having to remember every truthy and falsy value while reviewing validation code. The Truthy and Falsey Values guide covers that mental model in more detail.

Also watch for accidental assignment inside predicates:

const hasAdmin = users.some((user) => (user.role = "admin"));

That mutates the first user and returns the assigned string, which is truthy. The result will be true for the wrong reason. Use comparison:

const hasAdmin = users.some((user) => user.role === "admin");

Small typo. Large mess. JavaScript, in its usual generous mood, will let you have both.

Combining some and every in status objects

Real screens often need more than one boolean. Keep each question named.

function getReleaseStatus(checks) {
  const hasBlockers = checks.some((check) => check.status === "blocked");
  const allRequiredPassed =
    checks.length > 0 &&
    checks.every((check) => {
      if (!check.required) return true;
      return check.status === "passed";
    });

  return {
    hasBlockers,
    allRequiredPassed,
    canRelease: !hasBlockers && allRequiredPassed,
  };
}

The important part is not the object. It is the separation:

  • hasBlockers asks whether any bad thing exists.
  • allRequiredPassed asks whether every required thing passed.
  • canRelease combines the named answers.

That is easier to debug than one large condition trying to be a whole policy department.

When filter or find is the better method

Use filter when you actually need the matching records:

const failedChecks = checks.filter((check) => check.status === "failed");

Use find when you need the first matching record:

const firstFailedCheck = checks.find((check) => check.status === "failed");

Use some when you only need to know whether a match exists:

const hasFailedCheck = checks.some((check) => check.status === "failed");

Those three lines ask different questions. The return type should make that obvious before anyone reads the callback. For a deeper comparison of the record-returning methods, see map vs filter vs find.

Key Takeaways

  • Use some for any-match questions that should return true or false.
  • Use every for all-match questions where one failure should fail the result.
  • Do not build a filtered array just to check whether a match exists.
  • Remember that [].every(...) returns true; add a length check when your rule requires at least one item.
  • Keep predicates explicit in validation and permission code, where truthy shortcuts can hide bugs.
Share this article:
javascriptarraysfundamentalsfunctional