DESIGN / CODE / INFRA / AI

解説

最初の1件と全部の一致を分ける:JavaScriptのfindとfilterを試そう

条件に合う最初の要素を返すfindと、一致した要素の配列を返すfilter。該当なしのundefinedと空配列も含め、同じデータで比べる。

最初の1件と全部の一致を分ける:JavaScriptのfindとfilterを試そう
保存リストを見る →
この記事の道しるべ 5項目

一覧から条件に合うデータを取り出したい。findとfilterはどちらも条件を調べるけれど、返すものが違うよ。最初の1件が欲しいのか、該当する全部が欲しいのかで選ぼう。

今回は三つの架空データを使う。ブラウザだけで操作できる作例を用意し、条件を変えた後の返り値をそのまま表示する。外部への検索や保存はしない。

同じ条件を二つの方法へ渡す

const items = [
  { id: "A", kind: "book" },
  { id: "B", kind: "pen" },
  { id: "C", kind: "book" },
];
const first = items.find(item => item.kind === "book");
const all = items.filter(item => item.kind === "book");

findは、先頭から条件を確かめ、最初に合った要素を返す。今回はidがAのオブジェクトだよ。filterは、条件に合う要素を集めた新しい配列を返すので、AとCの二つが入る。

「同じ条件だから同じ結果」とは限らない。返り値が要素そのものか配列かによって、後ろの処理も変わる。

見つからないときも、返り値が違う

const first = items.find(item => item.kind === "eraser");
const all = items.filter(item => item.kind === "eraser");
console.log(first);      // undefined
console.log(all.length); // 0

findでは見つからないとundefined、filterでは空配列になる。今回のデータはオブジェクトだけなので、findの結果がundefinedなら一致なしと読める。

空配列はJavaScriptでは真として扱われる値。if(all)だけでは「結果が1件以上あるか」は判断できないよ。件数を見るならall.lengthを確認しよう。

作例でbook・pen・eraserを選ぶ

  1. bookを選ぶ。findはA、filterはAとCになる。
  2. penを選ぶ。findはB、filterはBが入った1要素の配列になる。
  3. eraserを選ぶ。undefinedと[]の違いを確認する。
  4. 「最初から試す」でbookへ戻す。

作例は元の一覧も表示する。findとfilterが、一覧そのものの順序を並べ替える処理ではないことも確認しよう。表示にはtextContentを使い、結果をHTMLとして解釈しない。

新しい配列でも、要素の中身までコピーされるわけではない

filterが新しい配列を返しても、中にあるオブジェクトは元の要素への参照になる。取り出した要素のプロパティを変更するなら、元データへの影響も考える必要があるよ。

findも元の要素を返す。今回は比較だけを行い、返ってきたオブジェクトを書き換えない作例にしている。配列が別かどうかと、要素の中身が独立しているかどうかを分けよう。

結果を読む前に確認すること

表示順を変えると、findが返す最初の要素も変わり得る。データの順番に意味があるか、条件が同じ型同士で比較されているかも確認したいね。

編集部ではNode.jsとChromiumで三つの条件、元一覧の保持、該当なし、リセットを確認した。並べ替えで元を残す考え方はsortとtoSortedも合わせて読んでみよう。

動かしてみよう:最初の一致と全部の一致

book・pen・eraserを選び、findとfilterの返り値と件数を見よう。

参考・出典

公開と変更の記録
  • :初回公開

日時は日本時間です。記載のある変更は、確認できた編集記録に基づきます。更新日の違いだけから変更内容を推測して載せることはありません。

更新・訂正の方針 →

みんなのコメント 0

感想や、試してみたことを聞かせてね。コメント・返信は承認後に公開されます。

最初のコメントをどうぞ。