1. ホーム
  2. JavaScript

【JavaScript】find・findIndex・some・every の使い方|配列から条件に合う要素を探す

Share

配列の中から「条件に合う要素」を探したい場面はよくあります。たとえば「IDが一致するユーザーを取り出す」「在庫切れの商品が1つでもあるか調べる」「全員が成人かどうか確認する」といったケースです。JavaScript には、こうした検索や判定を簡潔に書ける find()findIndex()some()every() という配列メソッドがあります。この記事では、4つのメソッドの使い方と戻り値の違い、よく似た filter()indexOf() との使い分けまでを、初心者の方にも分かるように解説します。

なぜ find 系・some・every を使うのか

配列から条件に合う要素を探すだけなら for 文でも書けますが、コードが長くなりがちで「何を探しているのか」が読み取りにくくなります。これらのメソッドは「各要素を条件で判定する関数(コールバック)」を渡すだけで目的を表現できるため、意図が一目で分かるのが利点です。4つはどれも同じ形で書きますが、返ってくる値(戻り値)が異なります。まずはそれぞれを順番に見ていきましょう。

find()|条件に合う「最初の要素」を取り出す

find() は、条件を満たす最初の要素そのものを返します。コールバックが true を返した時点で探索を止め、その要素を返すのが特徴です。

script.js
const numbers = [3, 8, 15, 22, 30];

// 10 より大きい最初の要素を探す
const found = numbers.find((n) => n > 10);

console.log(found); // 15

条件に合う要素が複数あっても、返るのは最初の1件だけです。条件に合う要素が1つも見つからなかった場合は undefined が返ります。この点は後の「見つからなかったときの戻り値」で詳しく触れます。

findIndex()|条件に合う最初の要素の「位置」を取得する

findIndex()find() とよく似ていますが、返すのは要素そのものではなくそのインデックス(位置番号)です。配列の要素を書き換えたり削除したりするために「何番目にあるか」を知りたいときに使います。

script.js
const numbers = [3, 8, 15, 22, 30];

// 10 より大きい最初の要素の位置を探す
const index = numbers.findIndex((n) => n > 10);

console.log(index); // 2(15 のインデックス)

インデックスが分かれば、numbers[index] で要素にアクセスしたり、splice() でその位置の要素を削除したりできます。条件に合う要素が見つからなかった場合は -1 が返ります。

some()|条件を満たす要素が「1つでもあるか」を調べる

some() は、配列の中に条件を満たす要素が1つでもあれば true、1つもなければ false を返します。戻り値は要素ではなく真偽値(true / false)です。「該当するものがあるか?」というイエス・ノーの判定に使います。

script.js
const numbers = [3, 8, 15, 22, 30];

// 20 より大きい要素が1つでもあるか
console.log(numbers.some((n) => n > 20)); // true

// 100 より大きい要素が1つでもあるか
console.log(numbers.some((n) => n > 100)); // false

some() は条件を満たす要素を見つけた時点で true を返して探索を止めるため、最後まで調べ続けるとは限りません。「在庫切れの商品が含まれているか」「未入力の項目があるか」といった確認に向いています。

every()|「すべての要素」が条件を満たすかを調べる

every() は、配列のすべての要素が条件を満たすときに true、1つでも満たさない要素があれば false を返します。こちらも戻り値は真偽値です。「全員が条件を満たしているか」を確認したいときに使います。

script.js
const numbers = [3, 8, 15, 22, 30];

// すべての要素が 0 より大きいか
console.log(numbers.every((n) => n > 0)); // true

// すべての要素が 10 より大きいか
console.log(numbers.every((n) => n > 10)); // false(3 や 8 が条件を満たさない)

every() は条件を満たさない要素を見つけた時点で false を返して探索を止めます。「フォームの全項目が入力済みか」「全商品が在庫ありか」といった全件チェックに便利です。

4つのメソッドの違いを整理する

ここまで見てきた4つのメソッドは、書き方は同じでも戻り値と用途が異なります。表で比べると違いがはっきりします。

メソッド戻り値主な用途
find()条件に合う最初の要素(無ければ undefined条件に合う要素そのものを取り出す
findIndex()条件に合う最初の要素のインデックス(無ければ -1要素の位置を調べて書き換え・削除する
some()真偽値(1つでも満たせば true該当する要素があるかを判定する
every()真偽値(すべて満たせば true全要素が条件を満たすかを判定する

「要素が欲しいなら find()」「位置が欲しいなら findIndex()」「あるか/ないかの判定なら some()every()」と覚えると、迷わず選べます。

オブジェクトの配列で使う実践例

これらのメソッドが本領を発揮するのは、オブジェクトの配列を扱うときです。コールバックの引数(ここでは user)に各要素が渡されるので、プロパティを使って条件を書けます。

script.js
const users = [
  { id: 1, name: "佐藤", age: 28, active: true },
  { id: 2, name: "鈴木", age: 17, active: false },
  { id: 3, name: "高橋", age: 34, active: true },
];

// id が 3 のユーザーを取り出す(find)
const user = users.find((u) => u.id === 3);
console.log(user); // { id: 3, name: "高橋", age: 34, active: true }

// id が 2 のユーザーの位置を調べる(findIndex)
const index = users.findIndex((u) => u.id === 2);
console.log(index); // 1

// 未成年(18歳未満)が含まれているか(some)
console.log(users.some((u) => u.age < 18)); // true

// 全員がアクティブか(every)
console.log(users.every((u) => u.active)); // false

このように、ID での1件取得は find()、位置の特定は findIndex()、条件の有無の判定は some() / every() と、目的に応じて自然に書き分けられます。

filter() や indexOf() との使い分け

find() と filter() の違い

条件で要素を探すメソッドとしては filter() もよく使われますが、両者は返すものが違います。find()条件に合う最初の1件(要素そのもの)を返すのに対し、filter()条件に合うすべての要素を集めた新しい配列を返します。

script.js
const numbers = [3, 8, 15, 22, 30];

// find は最初の1件(要素)
console.log(numbers.find((n) => n > 10));   // 15

// filter は該当する全件(配列)
console.log(numbers.filter((n) => n > 10)); // [15, 22, 30]

「1件だけ欲しい」のに filter() を使うと、わざわざ [0] で先頭を取り出す手間がかかり、該当が無いときの扱いも面倒になります。1件取得が目的なら find() を選びましょう。逆に「条件に合うものを全部集めたい」なら filter() です。

findIndex() と indexOf() の違い

位置を調べる indexOf() もありますが、こちらは値が完全に一致する要素を探すメソッドです。複雑な条件やオブジェクトのプロパティでは探せません。「 age が18未満の要素」のような条件で位置を知りたいときは findIndex() を使います。

script.js
const fruits = ["apple", "banana", "cherry"];

// indexOf は値の一致で位置を探す
console.log(fruits.indexOf("banana")); // 1

// findIndex は条件式で位置を探せる
console.log(fruits.findIndex((f) => f.startsWith("c"))); // 2

単純な値の一致なら indexOf()、条件式で判定したいなら findIndex()、という使い分けです。

見つからなかったときの戻り値に注意する

find は undefined、findIndex は -1 を返す

条件に合う要素が無いとき、find()undefinedfindIndex()-1 を返します。この違いを意識せずに使うと、思わぬエラーにつながります。たとえば find() の戻り値をそのままプロパティ参照すると、見つからなかったときに undefined.name となってエラーになります。

script.js
const users = [{ id: 1, name: "佐藤" }];

const user = users.find((u) => u.id === 99); // 見つからない
console.log(user); // undefined

// そのまま参照するとエラー
// console.log(user.name); // TypeError

// 見つかった場合だけ参照する(オプショナルチェーン)
console.log(user?.name); // undefined(エラーにならない)

見つからない可能性があるときは、上の例のようにオプショナルチェーン(?.)を使ったり、if (user) で存在を確認してから処理したりすると安全です。findIndex() の場合は -1 が「見つからなかった」を意味するので、if (index !== -1) のように判定します。

空配列に every を使うと true になる

意外と見落としがちなのが、空の配列に every() を使うと、条件に関係なく必ず true が返るという挙動です。「すべての要素が条件を満たす」という判定は、判定すべき要素が1つも無ければ「満たさない要素も無い」とみなされるためです。一方、空配列の some() は必ず false になります。

script.js
const empty = [];

console.log(empty.every((n) => n > 10)); // true
console.log(empty.some((n) => n > 10));  // false

配列が空になりうる場面で every() を「全員が合格か」のような判定に使うときは、先に array.length > 0 で空でないことを確認しておくと、意図しない true を防げます。

まとめ

find()findIndex()some()every() は、配列から条件に合う要素を探したり判定したりするための便利なメソッドです。要点を振り返っておきましょう。

  • find() は条件に合う最初の要素を返す(無ければ undefined
  • findIndex() は条件に合う最初の要素のインデックスを返す(無ければ -1
  • some() は1つでも条件を満たせば trueevery() はすべて満たせば true
  • 1件取得は find()、全件取得は filter() と使い分ける
  • 見つからないときの戻り値(undefined / -1)と、空配列の every()true になる点に注意

「要素が欲しいのか、位置が欲しいのか、ある/ないを知りたいのか」を意識すれば、4つのメソッドは迷わず選べます。for 文で書いていた検索処理を、ぜひこれらのメソッドで簡潔に置き換えてみてください。

参考ページ