
JavaScriptの配列操作のfilter()で1件だけ取ってませんか?filter()とfind()の使い分け方
はじめに
皆さんは配列内の要素を取得する際にどのようなコードを書いているでしょうか?JavaScriptの配列には、filter()とfind()という、要素を抽出する時に便利な2つのメソッドがあります。これらは似たような処理を行いますが、目的と結果が異なります。
本記事では、このfilter()とfind()の違いと、目的を明確にし、状況に応じて適切なメソッドを選べるよう特徴を簡潔にご紹介します。
filter()の基本「複数の結果を抽出する」
filter() は、条件に合致した要素だけで構成される新しい配列を生成します。なおこの新しい配列は、元の配列のシャローコピー(浅いコピー)です。
オブジェクトのシャローコピーとは、コピーがコピー元のオブジェクトとプロパティにおいて同じ参照を共有する(同じ基礎値を指す)コピーのことを指します。その結果、コピー元とコピー先のどちらかを変更すると、もう一方のオブジェクトも変更される可能性があります。
もし合致する要素が1つもなかった場合、filter() は空の配列([])を返します。
構文の特徴
filter() は反復処理メソッドであり、配列のそれぞれの要素に対してコールバック関数を実行します。
- 引数には、抽出条件を指定したコールバック関数を指定する。
- コールバック関数の引数には、現在処理中の要素が渡される。
- コールバック関数の戻り値がtrueであれば、その要素は新しい配列に保持される。falseであれば保持されない。
記述例
const items = [10, 20, 30, 40];
// filter: 条件に合うすべてを配列で返す
console.log(items.filter(x => x > 25)); // [30, 40]find()の基本「最初に一致した要素を抽出する」
find() は、配列の要素に対してコールバック関数を順に実行し、コールバック関数がtrueを返した時点で配列の反復処理は直ちに停止します。これが filter() との最も重要な違いです。filter() はすべての要素をチェックしますが、find() は最初に見つかった時点で処理を切り上げます。
もし条件を満たす要素が配列内に1つもない場合、find() はundefinedを返します。
構文の特徴
- 引数には、抽出条件を指定したコールバック関数を指定します。
- コールバック関数の引数には、現在処理中の要素が渡されます。
- コールバック関数の戻り値がtrueになると、find()はその要素を返し、反復処理を終了します。
記述例
const items = [10, 20, 30, 40];
// find: 最初の1件だけ返す
console.log(items.find(x => x > 25)); // 30両者の使い分け
filter()の特徴
- 目的:複数の要素を抽出/絞り込みたい
- 戻り値の型:常に配列(シャローコピー)
- 処理:配列の最後まで実行される
find()の特徴
- 目的:最初に一致した単一の要素を探したい
- 戻り値の型:要素自体、または undefined
- 処理:見つけた時点で直ちに停止する
なぜ filter() を避けるべきか
また、単一の結果が欲しいのに、結果が配列として返ってくるのも意図に反します。
まとめ
- 「結果として複数の要素が欲しい」なら filter()。
- 「結果として単一の値が欲しい」なら find()。
参考情報
- https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/filter
- https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/find
- https://developer.mozilla.org/ja/docs/Glossary/Shallow_copy
カサレアルでは複数のJavaScirptのコースを開催しています。
コースの詳細や開催日程に関しては以下のリンクをご覧ください。
https://www.casareal.co.jp/ls/service/openseminar/search/frontend