1. ホーム
  2. JavaScript

【JavaScript】配列の map / filter / reduce の使い方を解説|違いと使い分け

Share

JavaScript で配列を扱うとき、for 文の代わりによく使われるのが map / filter / reduce です。この3つを使い分けられると、配列の「変換・絞り込み・集計」がとても短く読みやすく書けます。この記事では、それぞれの違いと使い方を実例で解説します。

map / filter / reduce の違い

まず、3つの役割をざっくり押さえておきましょう。いずれも配列の各要素に対して関数を実行しますが、返すものが違います。

メソッド役割
map各要素を変換して、同じ数の新しい配列を作る
filter条件に合う要素だけを絞り込んだ新しい配列を作る
reduce全要素を1つの値にまとめる(合計や最大値など)

いずれも元の配列は変更せず、新しい結果を返すのが特徴です。

map:各要素を変換する

map() は、各要素に処理を加えた新しい配列を返します。要素数は変わりません。たとえば、すべての数値を2倍にしてみます。

script.js
const numbers = [1, 2, 3, 4];

// 各要素を2倍にした新しい配列を作る
const doubled = numbers.map((num) => num * 2);

console.log(doubled); // [2, 4, 6, 8]
console.log(numbers); // [1, 2, 3, 4](元の配列は変わらない)

「リストの各データを表示用の形に整える」といった場面で頻繁に使います。

filter:条件で絞り込む

filter() は、条件(true / false を返す関数)に合う要素だけを残した新しい配列を返します。要素数は減ることがあります。偶数だけを取り出してみます。

script.js
const numbers = [1, 2, 3, 4, 5, 6];

// 偶数だけを残す(trueを返したものだけ残る)
const evens = numbers.filter((num) => num % 2 === 0);

console.log(evens); // [2, 4, 6]

コールバック関数が true を返した要素だけが残ります。「条件に合うものだけ抜き出す」ときに使います。

reduce:1つの値にまとめる

reduce() は、配列を順番にたどりながら値を蓄積し、最終的に1つの値を返します。合計を求める例を見てみましょう。

script.js
const numbers = [1, 2, 3, 4];

// 合計を求める(初期値0からスタート)
const total = numbers.reduce((sum, num) => sum + num, 0);

console.log(total); // 10

第1引数の関数は、第1引数に「これまでの蓄積値(sum)」、第2引数に「現在の要素(num)」を受け取ります。reduce() の第2引数 0 は蓄積値の初期値です。初期値は付け忘れやすいので注意しましょう。

組み合わせて使う(メソッドチェーン)

3つは . でつなげて連続して使えます。「200円以下の商品の合計金額」を求めてみます。filter で絞り込み、map で価格だけ取り出し、reduce で合計する、という流れです。

script.js
const products = [
  { name: 'りんご', price: 100 },
  { name: 'みかん', price: 80 },
  { name: 'ぶどう', price: 300 },
];

// 200円以下の商品の合計金額
const total = products
  .filter((p) => p.price <= 200) // 200円以下に絞る
  .map((p) => p.price)           // 価格だけ取り出す
  .reduce((sum, price) => sum + price, 0); // 合計する

console.log(total); // 180

このように、for 文で書くと長くなる処理を、意味のわかる短いコードで表現できます。

思った結果にならないときは

undefined が並んだ配列が返ってきたり、期待した値にならなかったりするときは、次のようなところでつまずいていることが多いです。

map と forEach を取り違えている

変換した「新しい配列」が欲しいときは map、ただ各要素に対して処理を繰り返したいだけなら forEach を使います。forEach は値を返さないため、結果を変数に受け取ろうとすると undefined になります。「新しい配列を作りたいのか、繰り返したいだけなのか」で選びましょう。

return を忘れている

コールバックを { } で囲んだ場合は、return を書かないと値が返りません。その結果、map なら undefined が並んだ配列になります。(num) => num * 2 のように { } を省いた書き方なら自動で返されますが、複数行で処理を書くときは return の付け忘れに注意してください。

reduce の初期値を指定していない

reduce の第2引数(初期値)は省略できますが、省略すると配列の最初の要素が初期値として使われ、空配列に対してはエラーになります。意図しない結果を避けるため、合計なら 0、文字列の連結なら '' のように、初期値を明示しておくのがおすすめです。

まとめ

map / filter / reduce は、配列処理の定番メソッドです。役割で使い分けましょう。

  • map:各要素を変換して、同じ数の配列を作る
  • filter:条件に合う要素だけ残す
  • reduce:全要素を1つの値にまとめる(初期値を忘れずに)
  • 3つは . でつなげて組み合わせられる

まずは mapfilter から使い始め、慣れてきたら reduce やメソッドチェーンに広げていくのがおすすめです。

参考リンク