Array.prototype.filter()

filter() は配列の各要素を関数に通し、true になった要素だけを集めた新しい配列を返します。元の配列は変わりません。要素数は減ることがあります。

実行して検証済み処理系Node 22.22.3対応ES5難易度●●○○○目安7更新

filter() は、配列の1つ1つを関数に通して、戻り値が真になった要素だけを集めた新しい配列を返します。 元の配列は変わりません。要素数は減ることがあります

example.js
出力書き換えて実行できます
Ctrl+Enter でも実行JS · UTF-8
[ 2, 4 ] [ 1, 2, 3, 4, 5 ]
example.js
出力書き換えて実行できます
Ctrl+Enter でも実行JS · UTF-8
[] 0 true

上のコードは書き換えて実行できます。n % 2 === 0n > 3 にしてみてください。

何が返るのか

中身
戻り値 新しい配列。長さは元以下
元の配列 変わらない
呼ばれる回数 要素の数だけ
1つも通らなかったとき 空配列null ではない)

filter()非破壊的メソッドです。

1つも通らなくても null にならない

見つからなかったときに nullundefined が返ると思って書くと、そこで詰まります。 必ず配列が返ります

example.js
出力書き換えて実行できます
Ctrl+Enter でも実行JS · UTF-8
[ 'a', 'c' ]
example.js
出力書き換えて実行できます
Ctrl+Enter でも実行JS · UTF-8
[ 'a', 'b', 'c' ]

判定は if (even) ではなく even.length === 0 で書きます。 空配列は truthy ですif (even) は必ず通ってしまいます。

コールバック関数が受け取るもの

map() と同じで、3つの引数が渡されます。

javascript
const nums = [0, 1, 2, 3];

const picked = nums.filter(n => n);

console.log(picked);
[ 1, 2, 3 ]
example.js
出力書き換えて実行できます
Ctrl+Enter でも実行JS · UTF-8
[ { id: 2, name: 'ゆうと' }, { id: 3, name: 'ゆうと' } ] { id: 2, name: 'ゆうと' }

真偽値でなくてもよい(truthy / falsy で判定される)

戻り値は true / false でなくて構いません。truthyなら残り、falsyなら落ちます。

この性質を使うと、空の値をまとめて落とす書き方ができます。

example.js
出力書き換えて実行できます
Ctrl+Enter でも実行JS · UTF-8
[ 1, <1 empty item>, 3 ] [ 1, 3 ] 2
javascript
const nums = [1, 2, 3];

const result = nums.filter((n) => {
nums.push(n * 10);
return true;
});

console.log(result);
console.log(nums.length);
[ 1, 2, 3 ] 6

filter(Boolean) は「falsy を全部落とす」という意味になります。

falsy は false / 0 / -0 / 0n / '' / null / undefined / NaN の8つだけです。それ以外は全部 truthy です。

よくある間違い

値を返してしまう

filter() に渡すのは残すかどうかの判定です。値を返すと、その値が truthy かどうかで判定されます。

0意図せず落ちましたn を残したいのではなく n が falsy かどうかを見ています。 値を変換したいときは filter() ではなく map() を使います。

1件だけ欲しいのに filter を使う

先頭の1件だけが欲しいなら find() です。 filter()最後まで全部見ます

戻り値 見つからないとき どこまで見るか
filter() 配列 空配列 最後まで
find() 要素そのもの undefined 見つかった時点で止まる

find()undefined を返したことに気づかず、そのままプロパティを読むと Cannot read properties of undefined になります。空振りしたときにどうするかを、その場で決めてください。

穴のあいた配列では、穴が消える

要素が入っていない位置(疎な配列の穴)ではコールバック関数が呼ばれません。 そして結果の配列に穴は残りません。ここが map() と違います。

map()長さを保つので穴がそのまま残り、filter()通ったものを詰め直すので穴が消えます。

表示のしかたは処理系によって違います。上は Node 22.22.3 の出力です。

途中で元の配列を変えない

filter() は走り始めた時点の長さを覚えています。実行中に要素を足しても見に行きません

元の配列は6件に増えたのに、結果は3件のままです。 ループの中で元の配列を変えない。これは map() でも forEach() でも同じです。

この記事の根拠

  1. Array.prototype.filter — ECMAScript® 2026 Language Specificationtc39.es
  2. Array.prototype.filter() — MDNdeveloper.mozilla.org

掲載しているコード例は、公開前に読み手が押したときに動くのと同じもので実行して出力を突き合わせています。結果はリポジトリに残しています。

このページの原文(Markdown)