filter とは何か
filter は「配列から、条件を満たす要素だけを“抽出して新しい配列”を返す」メソッドです。元の配列は変更しない非破壊操作で、返される配列の要素数は条件次第で増減します。ここが重要です:filter は“選別(ふるい)専用”。副作用を入れず、真偽値で「残す/捨てる」をはっきり書くほど読みやすく、バグを防げます。
基本構文と戻り値
最もシンプルな使い方
const nums = [1, 2, 3, 4, 5];
const evens = nums.filter(n => n % 2 === 0);
console.log(evens); // [2, 4]
console.log(nums); // [1, 2, 3, 4, 5](元は不変)
JavaScriptコールバック関数が true を返した要素だけが残り、false のものは捨てられます。結果は“新しい配列”なので、参照共有の副作用を避けられます。
オブジェクト配列の抽出
const products = [
{ name: "A", stock: 0, price: 100 },
{ name: "B", stock: 5, price: 200 },
{ name: "C", stock: 3, price: 150 }
];
const inStock = products.filter(p => p.stock > 0);
// [{ name: "B", stock: 5, price: 200 }, { name: "C", stock: 3, price: 150 }]
JavaScriptプロパティ条件での選別が直感的に書けます。複合条件は論理演算子(&&、||)で明確に表現します。
コールバックの引数と thisArg
value・index・array が渡される
const arr = [5, 12, 8, 20];
const bigAfterFirst = arr.filter((value, index, array) => {
// value: 今の値
// index: 位置
// array: 元の配列
return value > 10 && index > 0;
});
console.log(bigAfterFirst); // [12, 20]
JavaScriptインデックスや配列全体に基づく条件(位置条件、隣接比較など)も一つの関数で自然に書けます。
thisArg で文脈を渡す(必要なときだけ)
const cfg = { max: 50 };
const xs = [10, 60, 40];
const underMax = xs.filter(function (x) { return x <= this.max; }, cfg);
console.log(underMax); // [10, 40]
JavaScript通常は外部変数を直接参照(クロージャ)で十分ですが、this を使う設計なら thisArg が使えます。
よく使う抽出レシピ
文字列の部分一致(大小無視)
const q = "tokyo";
const cities = ["Tokyo", "Osaka", "Kyoto"];
const hits = cities.filter(c => c.toLowerCase().includes(q.toLowerCase()));
// ["Tokyo"]
JavaScript比較前に正規化(toLowerCase、trim)すると、意図通りの抽出が安定します。
必須タグを“すべて”含む記事だけ
const required = ["js", "web"];
const articles = [
{ title: "A", tags: ["js", "web"] },
{ title: "B", tags: ["js"] }
];
const matched = articles.filter(a =>
required.every(tag => a.tags.includes(tag))
);
// [{ title: "A", tags: ["js", "web"] }]
JavaScriptネストした配列は includes、some、every の組み合わせで表現力が上がります。
欠損除去(null/undefined を取り除く)
const xs = [undefined, 1, null, 2, 0];
const compact = xs.filter(x => x != null); // [1, 2, 0]
JavaScript!= null は null と undefined の両方を除外します。0 や “” を残したい場面で有効です。
重複除去(素朴な方法)
const xs = ["A", "B", "A"];
const dedup = xs.filter((x, i) => xs.indexOf(x) === i); // ["A", "B"]
JavaScript大量データや頻繁な判定では Set を使う方が高速です。
重要ポイントの深掘り(挙動・落とし穴・対策)
非破壊であること(安全に絞る)
filter は元配列を変更しません。絞り込み結果を別の配列として扱えるため、UI 状態管理(React/Vue)や参照共有でも安全です。
疎配列(空スロット)はコールバックが“呼ばれずスキップ”
const sparse = Array(3); // [ <3 empty items> ]
const out = sparse.filter(() => true);
console.log(out); // [](空スロットはそもそも判定されない)
JavaScript空スロットのスキップ挙動が意図に合わない場合、先に Array.from で正規化してから絞り込みます。
const normalized = Array.from(sparse, x => x ?? null);
JavaScript真偽値そのものを返す(副作用を入れない)
filter のコールバックは“残すか捨てるか”だけを返すのが基本です。外部状態を書き換える副作用を混ぜると、可読性と一貫性が落ちます。
パフォーマンス(O(n):前処理で効率化)
線形走査のため、重い判定(正規表現、外部 I/O)を毎要素に行うと遅くなります。事前の正規化(小文字化、トリム)、セット化(許可集合を Set に)でコストを下げましょう。
const allow = new Set(["png", "jpg", "gif"]);
const files = ["a.png", "b.txt"];
const ok = files.filter(f => allow.has(f.split(".").pop()?.toLowerCase()));
JavaScript他メソッドとの使い分けと組み合わせ
filter と map の順序
「絞ってから変換」する方が分かりやすく、無駄な変換を避けられます。
const labels = products
.filter(p => p.stock > 0)
.map(p => `${p.name} (${p.price})`);
JavaScriptfilter と reduce
filter は「選別」、reduce は「集約」。例えば“条件を満たすものの合計”は filter → reduce、または reduce 1本でも書けます。
const sum = products
.filter(p => p.stock > 0)
.reduce((acc, p) => acc + p.price, 0);
JavaScriptfilter と some/every
存在判定だけなら filter より some/every が軽く明確です。配列が欲しいときに filter、真偽値が欲しいときに some/every を選びます。
実践例(UI・API・データ整形)
入力検証:許可拡張子のみを通す
const allow = new Set(["png", "jpg", "gif"]);
function allowedFiles(files) {
return files.filter(f => allow.has(f.split(".").pop()?.toLowerCase()));
}
JavaScriptテーブル表示:検索ワードで行を絞る
function filterRows(rows, q) {
const s = q.trim().toLowerCase();
return rows.filter(r =>
r.name.toLowerCase().includes(s) ||
r.email.toLowerCase().includes(s)
);
}
JavaScriptAPI レスポンスのクレンジング
const raw = [{ id: 1 }, null, undefined, { id: 2 }];
const clean = raw.filter(x => x && typeof x.id === "number");
JavaScriptまとめ
filter は「条件を満たす要素だけを残して“新しい配列”を返す」非破壊メソッドです。コールバックは真偽値だけを返し、副作用を避けることで読みやすさと安定性が高まります。疎配列はスキップされるため、必要なら正規化(Array.from)を。重い判定は前処理やセット化で効率化し、目的によって map/reduce/some/every と使い分ける。これらを押さえれば、初心者でも直感的で壊れにくい“絞り込みロジック”を短く正確に書けます。
