find と includes で配列を検索する

生田 陸人
LuaGate エンジニア / 現役エンジニア
編集 LuaGate編集部

find と includes で配列を検索する とは

Array.prototype.find / findIndex / includes を使って、条件に合う要素や存在判定を簡潔に書く。

find と includes で配列を検索する

配列の中から「条件に合う要素」を探したい場面は日常茶飯事です。古典的には for ループを回して if で判定するわけですが、現代の JavaScript にはもっと宣言的な書き方が用意されています。findfindIndexincludesindexOf の 4 つを使い分けられれば、検索コードはぐっと短く読みやすくなります。

検索は 「何を返したいか」 で API を選ぶ。値そのものなら find、位置なら findIndex、有無だけなら includes

find は条件に合う最初の要素を返す

Array.prototype.find は、コールバックが true を返した最初の要素を返します。見つからなければ undefined です。

JavaScript

const users = [ { id: 1, name: "Alice" }, { id: 2, name: "Bob" }, { id: 3, name: "Carol" }, ]; const found = users.find((u) => u.id === 2); console.log(found); // { id: 2, name: "Bob" }

コールバックは要素ごとに呼ばれ、true を返した瞬間に走査が止まります。全部見て回らないので大きな配列でも効率的です。

findIndex は位置を返す

要素そのものではなく位置 (インデックス) が欲しいときは findIndex を使います。見つからなければ -1 を返します。

JavaScript

const idx = users.findIndex((u) => u.name === "Carol"); console.log(idx); // 2 const notFound = users.findIndex((u) => u.name === "Zoe"); console.log(notFound); // -1

見つからなかった時の戻り値は findundefinedfindIndex-1。これを忘れると if 判定でバグる。

includes は有無だけを boolean で返す

「ある値が配列に含まれているか?」だけ知りたいときは includes です。コールバックは渡さず、検索したい値を直接渡します。

JavaScript

const tags = ["js", "react", "node"]; console.log(tags.includes("react")); // true console.log(tags.includes("vue")); // false

indexOf も似た用途で使えますが、includes の方が真偽値で読みやすく、NaN の比較も正しく扱えます ([NaN].indexOf(NaN)-1[NaN].includes(NaN)true)。

動きを追ってみる

diagram (will load when visible)

図のとおり、find は要素を 1 つずつ調べ、最初に true を返した要素で走査を打ち切ります。見つからずに末尾まで到達したら undefined です。

filter との違い

似た名前の filter は、条件に合う全要素を配列で返します。find は最初の 1 つだけです。

JavaScript

const nums = [1, 2, 3, 4, 5]; nums.find((n) => n > 2); // 3 nums.filter((n) => n > 2); // [3, 4, 5]

用途で選びましょう。1 件取りたければ find、複数取りたければ filter です。

よくある間違い

第 1 に、find の結果をそのままプロパティアクセスすると、見つからなかったときに Cannot read properties of undefined で落ちます。オプショナルチェーン ?. やデフォルト値で対策します。第 2 に、findIndex の戻り値を if (idx) で判定すると idx === 0false 扱いになります。必ず if (idx !== -1) で書きます。第 3 に、includes はオブジェクトに対しては参照一致でしか動きません。同じ形でも別オブジェクトなら false です。

find で見つからなかったらどうするか、必ず早めに設計する。?.?? と組み合わせるのが定番。

やってみよう

配列 arr と検索値 target を受け取り、target が存在すればそのインデックス、無ければ -1 を返す indexOfValue 関数を書きましょう。return arr.findIndex((v) => v === target) の 1 行で完成です。代わりに arr.indexOf(target) でも同じ動作になりますが、ここでは findIndex の使い方に慣れることが目的です。includestrue/false を返すバリエーションも書いてみてください。

よくある質問

Q. ブラウザと Node.js で動作は変わりますか?

A. JavaScript の構文・組み込み機能(配列・文字列・Promise 等)はどちらでも同じです。違いは DOM API(ブラウザ専用)と fs などのファイル系(Node 専用)など、実行環境固有の機能です。コアロジックは両方で動くため、テストもしやすくなります。

Q. ES6 以降の新機能は使っても大丈夫ですか?

A. 現代のブラウザ・Node.js は ES2020 以降の機能をほぼサポートしています。古い IE 等を対象にする必要が無ければ、let/const、アロー関数、分割代入、async/await を積極的に使ってください。トランスパイル(Babel/Vite)が必要なケースは年々減っています。

Q. TypeScript に進む価値はありますか?

A. 型情報があるとリファクタやエディタ補完が劇的に効くため、規模が大きくなるなら TypeScript への移行を強くおすすめします。最初は any を許容しつつ徐々に型を付ければ、JS の知識をそのまま活かせます。

次のレッスン

次は 数値配列を昇順にソートする で、Array を学びます。

事前確認 — 進む前に次の 3 つができることを確認しましょう。

  1. find と includes の要点を自分の言葉で説明できる
  2. このレッスンの最小コード (または操作手順) を見ずに書ける
  3. 練習問題やクイズで間違えた箇所を読み直して理解した

理解度チェック (30 秒)

Q. find と includes とは何か、1 文で説明してください。

この章のポイント

A. 本文の「このレッスンで分かること」または冒頭の説明文を見直し、自分の言葉で要約できれば OK。詰まったら本レッスンの最初の H2 セクションを読み返してみましょう。

関連レッスン

要件

  1. Array.prototype.findIndex を使うこと
  2. 見つからないときは -1 を返すこと
  3. === で厳密一致を判定すること

入出力例

test-cases.txt

indexOfValue([10,20,30,40], 30)2 indexOfValue([5,6,7], 5)0 indexOfValue([1,2,3], 99)-1 indexOfValue([], 1)-1

ヒント

main.js
main.js
学習モード

メモ

find と includes で配列を検索する

⌘S で保存