Array.filter

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

Array.filter とは

filter で条件に合う要素だけを残す。本レッスンでは、Array.filter の基本から実際の使いどころまでを整理し、現場で迷わず使える形に落とし込みます。

filter で要素を絞り込む

map加工 なら、 filter絞り込み です。 Array.prototype.filter は配列の各要素に 条件 を与え、 true を返した要素だけを集めて新しい配列にしてくれます。 forif を使えば自分でも書けますが、 filter を使うとぐっと短く読みやすくなります。

filter配列を短くする メソッド、 map配列の中身を変える メソッド、と覚えると区別しやすいです。要素数は filter で減ることはあっても増えることはありません。

例えば「配列の中から偶数だけ取り出す」「ログインしているユーザーだけ残す」 「不要なデータを除外する」などに使えます。 JavaScript の現場で for ループを書く前に、まず filter で書けないか考える癖をつけましょう。

filter の文法

書き方は次のとおりです。

JavaScript

const nums = [1, 2, 3, 4, 5, 6]; const evens = nums.filter((n) => n % 2 === 0); console.log(evens); // [2, 4, 6] console.log(nums); // [1, 2, 3, 4, 5, 6] (元のまま)

コールバックは 要素 を受け取り、 booleanreturn します。 true なら残す、 false なら捨てる、というシンプルなルールです。

filter のコールバックも (element, index, array) の 3 引数を受け取れますが、ほとんどの場合は element だけで足ります。

JavaScript

const arr = [10, 25, 8, 14, 99]; const over20 = arr.filter((n) => n > 20); console.log(over20); // [25, 99]

コールバックの戻り値は厳密に true / false ではなく truthy / falsy でも構いません。例えば arr.filter(Boolean)null0 、空文字を一気に取り除けます。

動きを追ってみる

filter のフローはこんな感じです。

diagram (will load when visible)

各要素について 条件を満たすか を判定し、満たすものだけを新しい配列に集めるだけです。 map と組み合わせて filter().map() のように繋ぐと、 絞り込んでから加工 の流れも 1 行で書けます。

for + if と比較する

手書きでループを回した場合と比べてみます。

JavaScript

// for + if 版 const nums = [1, 2, 3, 4, 5, 6]; const evens = []; for (let i = 0; i < nums.length; i++) { if (nums[i] % 2 === 0) evens.push(nums[i]); } // filter 版 const evens2 = nums.filter((n) => n % 2 === 0);

for + if 版は i の管理や push の手順が見えますが、 filter 版は 条件 だけが残ります。条件式に名前を付ければさらに読みやすくなります。

JavaScript

const isEven = (n) => n % 2 === 0; const evens3 = nums.filter(isEven);

条件式を別の関数に切り出すと、テストもしやすくなり、複数の場所で再利用できます。 関数を値として扱う 高階関数のうれしさです。

filter ではできないこと

以下のとおりです。

  • 要素を加工して別の値にしたい → それは map の仕事
  • 配列を 1 つの値にまとめたい → それは reduce の仕事
  • 元の配列を直接削りたい → splice などを使うが、できるだけ filter で新しい配列を作る方が安全

filter元を変えない ので、 React などの状態管理とも相性抜群です。元の state を変更せずに 新しい配列 を作って差し替える、という流れにぴったりはまります。

よくある間違い

よくあるつまずきは次のとおりです。

  • filter のコールバックで return を書き忘れて、全要素が落ちる ( undefined は falsy)
  • filter の戻り値を捨ててしまい、元配列が変わると勘違いする
  • ==== を間違えて、 比較 のつもりが 代入 になっている

JavaScript

const arr = [1, 2, 3]; // NG — 戻り値を使っていない、元配列も変わらないので何も起きない arr.filter((n) => n > 1); console.log(arr); // [1, 2, 3] // OK — 戻り値を変数に受ける const filtered = arr.filter((n) => n > 1); console.log(filtered); // [2, 3]

戻り値を変数に受けないなら filter を使う意味はありません。 forEach を使うべき場面と区別しましょう。

やってみよう

配列 arr を受け取り、 filter を使って偶数だけ残した新しい配列を返す関数 keepEvens を書いてみましょう。元の配列は変更しません。空配列 [] のときは [] を返します。

よくある質問

Q. filter と find の違いは?

A. filter は条件を満たす要素を全部集めて配列で返し、find は最初に見つかった 1 件だけ返します。1 件だけ欲しいなら find の方が短絡評価で速く、空のとき undefined(Python の next は StopIteration)になる点に注意してください。

Q. filter の戻り値が空配列のときの扱いは?

A. JS の filter は常に配列を返すため、空でも .length で安全にチェックできます。Python の filter はイテレータを返すので list() で囲んでから使うか、内包表記 [x for x in items if cond] の方が分かりやすいことが多いです。

Q. filter と map をチェーンしても性能は大丈夫ですか?

A. 通常規模なら問題ありません。配列を 2 周することになるため、要素数が数百万を超える場合だけ reduce にまとめるか、JS なら array.reduce で 1 周にすることを検討してください。可読性は filter→map のチェーンが分かりやすいです。

次のレッスン

次は Array.reduce で、filter で条件に合う要素だけを残す を学びます。

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

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

理解度チェック (30 秒)

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

この章のポイント

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

関連レッスン

要件

  1. Array.prototype.filter を使う
  2. n % 2 === 0 で偶数判定する
  3. 条件に合う要素だけ残した新しい配列を return する

入出力例

test-cases.txt

keepEvens([1,2,3,4,5,6])[2,4,6] keepEvens([])[] keepEvens([1,3,5])[] keepEvens([0,-2,7,8])[0,-2,8]

ヒント

main.js
main.js
学習モード

メモ

Array.filter

⌘S で保存