JavaScript 配列の変換・集計:map・reduce・flatMap の使い方
配列を別の形に変換したり、合計・グループ化したりするには map・reduce・flatMap を使います。
早わかりまとめ
| メソッド | 戻り値 | 向いている用途 |
|---|---|---|
map |
新しい配列 | 各要素を変換した配列を作る |
reduce |
任意の値 | 配列を1つの値に集計する |
flatMap |
新しい配列 | 変換しながら1階層フラット化する |
flat |
新しい配列 | ネストした配列を平坦にする |
map:各要素を変換した新しい配列を作る
const prices = [100, 200, 300] // 税込み価格の配列を作る const withTax = prices.map((price) => Math.round(price * 1.1)) console.log(withTax) // [110, 220, 330]
オブジェクトの配列から特定のプロパティだけ取り出すときによく使います。
const users = [
{ id: 1, name: 'Alice', age: 25 },
{ id: 2, name: 'Bob', age: 30 },
]
// 名前だけの配列を作る
const names = users.map((user) => user.name)
console.log(names) // ['Alice', 'Bob']
// 整形した別のオブジェクトに変換
const labels = users.map((user) => ({
value: user.id,
label: `${user.name}(${user.age}歳)`,
}))
// [{ value: 1, label: 'Alice(25歳)' }, { value: 2, label: 'Bob(30歳)' }]
map は元の配列を変えず、必ず新しい配列を返します。
reduce:配列を1つの値に集計する
reduce は「配列を畳み込んで1つの値を作る」メソッドです。合計・最大値・グループ化など幅広く使えます。
// 合計を求める const numbers = [1, 2, 3, 4, 5] const sum = numbers.reduce((acc, num) => acc + num, 0) console.log(sum) // 15
第1引数がコールバック(acc:累積値、num:現在の値)、第2引数が初期値です。
最大値・最小値を求める
const scores = [40, 75, 90, 55] const max = scores.reduce((acc, score) => Math.max(acc, score), -Infinity) console.log(max) // 90
グループ化する
const items = [
{ category: 'fruit', name: 'apple' },
{ category: 'veggie', name: 'carrot' },
{ category: 'fruit', name: 'banana' },
]
const grouped = items.reduce((acc, item) => {
if (!acc[item.category]) {
acc[item.category] = []
}
acc[item.category].push(item.name)
return acc
}, {})
console.log(grouped)
// { fruit: ['apple', 'banana'], veggie: ['carrot'] }
重複を除いて集計する
const tags = ['js', 'css', 'js', 'html', 'css']
const unique = tags.reduce((acc, tag) => {
if (!acc.includes(tag)) acc.push(tag)
return acc
}, [])
console.log(unique) // ['js', 'css', 'html']
flatMap:変換しながらフラット化する
flatMap は map して flat(1) するのと同じ動作です。変換結果が配列になるとき(1件が複数件になるとき)に使います。
const sentences = ['hello world', 'foo bar']
// 単語の配列に分解する
const words = sentences.flatMap((s) => s.split(' '))
console.log(words) // ['hello', 'world', 'foo', 'bar']
// map だとネストが残る
const nested = sentences.map((s) => s.split(' '))
console.log(nested) // [['hello', 'world'], ['foo', 'bar']]
flat:ネストした配列を平坦にする
const nested = [1, [2, 3], [4, [5, 6]]] console.log(nested.flat()) // [1, 2, 3, 4, [5, 6]](1階層のみ) console.log(nested.flat(2)) // [1, 2, 3, 4, 5, 6](2階層) console.log(nested.flat(Infinity)) // [1, 2, 3, 4, 5, 6](すべて)
よく使うパターン:メソッドチェーン
filter・map・reduce はよく組み合わせて使います。
const orders = [
{ product: 'A', price: 1000, quantity: 2 },
{ product: 'B', price: 500, quantity: 0 },
{ product: 'C', price: 2000, quantity: 1 },
]
// 購入済み(quantity > 0)の合計金額を計算
const total = orders
.filter((order) => order.quantity > 0)
.map((order) => order.price * order.quantity)
.reduce((sum, amount) => sum + amount, 0)
console.log(total) // 4000(1000×2 + 2000×1)
まとめ
| したいこと | 使うもの |
|---|---|
| 各要素を別の形に変換する | map |
| 合計・最大値・グループ化など集計する | reduce |
| 変換しながらネストを1階層解除する | flatMap |
| ネストした配列を平坦にする | flat |
配列の絞り込みは「JavaScript 配列の絞り込み:filter・find・some の使い方」を参照してください。
配列の繰り返し処理は「JavaScript 配列の繰り返し:forEach・map・for...of の使い分け」を参照してください。