---
type: how-to
language: javascript
slug: array/sum
title: "配列の合計を出す"
title_tag: "JavaScript 配列の合計 — reduce と、小数・空配列の罠"
summary: >
  合計は reduce に初期値 0 を渡すのが基本です。小数がずれる理由、空配列で例外になる条件、
  オブジェクトの配列の合計、大きすぎる数の扱いまで、実行して確かめます。
description: >
  reduce に初期値 0 を渡すのが基本です。小数がずれる理由、空配列で例外になる条件、オブジェクトの配列の合計、安全に扱える整数の上限まで実行して確かめます。
status: published
difficulty: 2
minutes: 8

versions:
  verified: "Node 22.22.3"
  since: "ES5"
  deprecated: null
  removed: null

sources:
  - title: "Array.prototype.reduce — ECMAScript® 2026 Language Specification"
    url: "https://tc39.es/ecma262/#sec-array.prototype.reduce"
  - title: "Number.MAX_SAFE_INTEGER — ECMAScript® 2026 Language Specification"
    url: "https://tc39.es/ecma262/#sec-number.max_safe_integer"

terms: [累積値, 初期値, 丸め誤差]

links:
  related:
    - javascript/reference/array/reduce
    - javascript/why/float-precision
    - javascript/how-to/array/group

content_updated_at: 2026-09-07
published_at: 2026-09-07
---

## 答え

`reduce()` に[key:初期値 `0`]を渡します。

```js run
const nums = [1, 2, 3, 4];

console.log(nums.reduce((sum, n) => sum + n, 0));
```
```output
10
```

**初期値の `0` を省かないでください。** 空配列で例外になります（後述）。

上のコードは書き換えて実行できます。`0` を `100` にしてみてください。

## 空配列で落ちないこと

初期値が無く要素も無いと、返すものが決まらず[bad:例外]になります。

```js bad
console.log([].reduce((sum, n) => sum + n));
```
```output
TypeError: Reduce of empty array with no initial value
```

**空配列は普通に起こります。** `filter()` の結果が空、取得件数が0件、未入力。

```js run
const prices = [100, 250, 80];
const expensive = prices.filter(p => p >= 1000);

console.log(expensive);
console.log(expensive.reduce((sum, n) => sum + n, 0));
```
```output
[]
0
```

初期値があれば `0` が返ります。**合計は0件なら0**が自然です。

## 小数はずれる

**ここがいちばん多い事故です。**

```js bad
const prices = [0.1, 0.2, 0.3];

console.log(prices.reduce((sum, n) => sum + n, 0));
console.log(prices.reduce((sum, n) => sum + n, 0) === 0.6);
```
```output
0.6000000000000001
false
```

[num:2]進数で `0.1` を正確に表せないためで、`reduce()` のせいではありません。
理由は
[なぜ 0.1 + 0.2 は 0.30000000000000004 になるのか](/ja/javascript/why/float-precision/) にあります。

### 直しかた: 整数で足す

金額なら、**最小単位の整数**で持ちます。円なら円、ドルならセント。

```js run
const cents = [10, 20, 30];

const total = cents.reduce((sum, n) => sum + n, 0);

console.log(total);
console.log(total / 100);
```
```output
60
0.6
```

すでに小数で持っているなら、**足す前に整数へ寄せます。**

```js run
const prices = [0.1, 0.2, 0.3];

const total = prices.reduce((sum, n) => sum + Math.round(n * 100), 0) / 100;

console.log(total);
console.log(total === 0.6);
```
```output
0.6
true
```

[dim:桁数（ここでは 100）は扱う通貨に合わせます。円なら 1、ドルなら 100 です。]

## オブジェクトの配列を合計する

足したい値を取り出してから足します。

```js run
const items = [
  { name: 'りんご', price: 120, qty: 2 },
  { name: 'みかん', price: 80, qty: 3 },
];

console.log(items.reduce((sum, i) => sum + i.price, 0));
console.log(items.reduce((sum, i) => sum + i.price * i.qty, 0));
```
```output
200
480
```

**`map()` を挟むと読みやすくなります。**

```js run
const items = [
  { name: 'りんご', price: 120, qty: 2 },
  { name: 'みかん', price: 80, qty: 3 },
];

const total = items
  .map(i => i.price * i.qty)
  .reduce((sum, n) => sum + n, 0);

console.log(total);
```
```output
480
```

[dim:配列を1回余分に作りますが、この規模なら差は出ません。読みやすさを優先してください。]

## 値が数値とは限らないとき

フォームから来た値は文字列です。**そのまま足すと繋がります。**

```js bad
const inputs = ['10', '20', '30'];

console.log(inputs.reduce((sum, n) => sum + n, 0));
```
```output
0102030
```

`0 + '10'` が `'010'` になり、以降ずっと文字列です。

```js run
const inputs = ['10', '20', '30'];

console.log(inputs.reduce((sum, n) => sum + Number(n), 0));
```
```output
60
```

**数値に変換できないものが混ざると `NaN` になります。**

```js bad
const inputs = ['10', 'あ', '30'];

console.log(inputs.reduce((sum, n) => sum + Number(n), 0));
```
```output
NaN
```

`NaN` は[key:一度混ざると最後まで残ります]。どこで壊れたか分からなくなります。

**先に弾いてください。**

```js run
const inputs = ['10', 'あ', '30', ''];

const nums = inputs.map(Number).filter(Number.isFinite);

console.log(nums);
console.log(nums.reduce((sum, n) => sum + n, 0));
```
```output
[ 10, 30, 0 ]
40
```

**`''` が `0` として残っている**ことに注意してください。
`'あ'` は `NaN` になって落ちましたが、`''` は最後尾の `0` として生き残っています。
`Number('')` は `0` です。未入力を弾きたいなら、変換の前に落とします。

```js run
const inputs = ['10', 'あ', '30', ''];

const nums = inputs
  .filter(s => s.trim() !== '')
  .map(Number)
  .filter(Number.isFinite);

console.log(nums);
console.log(nums.reduce((sum, n) => sum + n, 0));
```
```output
[ 10, 30 ]
40
```

変換の詳しい話は
[文字列を数値に変換する](/ja/javascript/how-to/string/to-number/) にあります。

## 大きすぎる合計

合計が[num:9007199254740991]を超えると、[bad:正確でなくなります]。

```js bad
const big = [9007199254740991, 1, 1];

console.log(big.reduce((sum, n) => sum + n, 0));
```
```output
9007199254740992
```

`1` を[num:2]回足したのに、[num:1]しか増えていません。

**`BigInt` で足します。**

```js run
const big = [9007199254740991n, 1n, 1n];

console.log(big.reduce((sum, n) => sum + n, 0n));
```
```output
9007199254740993n
```

初期値も `0n` にする必要があります。[bad:`0` と `0n` は足せません]。

```js bad
console.log([1n, 2n].reduce((sum, n) => sum + n, 0));
```
```output
TypeError: Cannot mix BigInt and other types, use explicit conversions
```

## 他のやり方

```js run
const nums = [1, 2, 3, 4];

let byLoop = 0;
for (const n of nums) byLoop += n;

console.log(nums.reduce((sum, n) => sum + n, 0));
console.log(byLoop);
```
```output
10
10
```

| 書き方 | 空配列 | 向いている場面 |
|---|---|---|
| `reduce(…, 0)` | [em:0 が返る] | ほぼ常にこれ |
| `for...of` で足す | [em:0 が返る] | 途中で抜けたい・条件が複雑なとき |
| `reduce()`（初期値なし） | [bad:例外] | 使わない |

**どちらでも構いません。** `reduce()` のほうが「合計を作っている」と読めます。

`reduce()` そのものの説明は
[Array.prototype.reduce()](/ja/javascript/reference/array/reduce/) にまとめてあります。
キーごとに分けて合計したいなら
[配列をキーごとにまとめる](/ja/javascript/how-to/array/group/) を見てください。
