概要
隣り合う 2 つの配列要素に対して(左から右へ)同時に関数を適用し、単一の値にします。
構文
var result = array.reduce(callback[, initialValue]);
引数
callback
- 4 つの引数を取って、配列内の各値に対し実行するコールバック関数
previousValue
- 現在処理されている配列要素の 1 つ前の要素。もしくは、
initialValue
。initialValue
については、後で述べます。 currentValue
- 現在処理されている配列要素
index
- 現在処理されている配列要素のインデックス
array
reduce
に呼ばれた配列
initialValue
callback
の最初の呼び出しのときに、最初の実引数として用いるためのオブジェクト。
詳細
reduce
は、配列に存在するおのおのの要素に対して、callback
関数を一度だけ実行します。配列における穴は対象からはずされ、また callback
関数は 「初期値(あるいは、直前の callback
呼び出し)」、「現在の要素の値」、「現在のインデックス」、「繰り返しが行われる配列」 の 4 つの引数を受け取ります。
reduce の callback
の呼び出しは、以下のように見えるでしょう。:
arrayObj.reduce(function(previousValue, currentValue, index, array){ // ... })
関数が呼び出される初回は、 previousValue
と currentValue
は 2 つの値のうちの 1 つを取り得ます。reduce
呼び出し時に、initialValue
が与えられた場合、previousValue
は initialValue
と等しくなり、currentValue
は、配列の最初の値と等しくなります。 initialValue
が与えられなかった場合、previousValue
は配列の最初の値と等しくなり、currentValue
は、2 番目の値と等しくなります。
次のコードのように reduce
を使用した場合について見てみましょう。
[0,1,2,3,4].reduce(function(previousValue, currentValue, index, array){ return previousValue + currentValue; });
コールバック関数は 4 回呼び出され、各回の引数の内容は以下のようになっています。
previousValue |
currentValue |
index |
array |
戻り値 | |
---|---|---|---|---|---|
初回の呼出し | 0 |
1 |
1 |
[0,1,2,3,4] |
1 |
2 回目の呼出し | 1 |
2 |
2 |
[0,1,2,3,4] |
3 |
3 回目の呼出し | 3 |
3 |
3 |
[0,1,2,3,4] |
6 |
4 回目の呼出し | 6 |
4 |
4 |
[0,1,2,3,4] |
10 |
reduce
の戻り値は、コールバック関数の最後の戻り値である(10
)となるでしょう。
reduce
の 第二引数に初期値を設定した場合は、コールバック各回の内部的な動作はこのようになります。
[0,1,2,3,4].reduce(function(previousValue, currentValue, index, array){ return previousValue + currentValue; }, 10);
previousValue |
currentValue |
index |
array |
戻り値 | |
---|---|---|---|---|---|
初回の呼出し | 10 |
0 |
0 |
[0,1,2,3,4] |
10 |
2 回目の呼出し | 10 |
1 |
1 |
[0,1,2,3,4] |
11 |
3 回目の呼出し | 11 |
2 |
2 |
[0,1,2,3,4] |
13 |
4 回目の呼出し | 13 |
3 |
3 |
[0,1,2,3,4] |
16 |
5 回目の呼出し | 16 |
4 |
4 |
[0,1,2,3,4] |
20 |
reduce
の戻り値はもちろん 20
となります。
互換性
reduce
は、ECMA-262 第 5 版に追加された仕様であり、他の標準の実装には存在しない場合があります。以下のコードをあなたのスクリプトの最初に挿入することにより、実装の如何に関わらずこれを動作させる事ができます。
if (!Array.prototype.reduce) { Array.prototype.reduce = function reduce(accumulator){ if (this===null || this===undefined) throw new TypeError("Object is null or undefined"); var i = 0, l = this.length >> 0, curr; if(typeof accumulator !== "function") // ES5 : "If IsCallable(callbackfn) is false, throw a TypeError exception." throw new TypeError("First argument is not callable"); if(arguments.length < 2) { if (l === 0) throw new TypeError("Array length is 0 and no second argument"); curr = this[0]; i = 1; // start accumulating at the second element } else curr = arguments[1]; while (i < l) { if(i in this) curr = accumulator.call(undefined, curr, this[i], i, this); ++i; } return curr; }; }
例
例: 配列内の値を全て足す
var total = [0, 1, 2, 3].reduce(function(a, b) { return a + b; }); // total == 6
例: 二次元配列を 一次元配列にする
var flattened = [[0, 1], [2, 3], [4, 5]].reduce(function(a, b) { return a.concat(b); }); // flattened is [0, 1, 2, 3, 4, 5]
ブラウザ実装状況
Kangax's compat tables に基づく。
機能 | Firefox (Gecko) | Chrome | Internet Explorer | Opera | Safari |
---|---|---|---|---|---|
基本サポート | 3.0 (1.9) | (有) | 9 | 10.5 | 4.0 |
機能 | Firefox Mobile (Gecko) | Android | IE Mobile | Opera Mobile | Safari Mobile |
---|---|---|---|---|---|
基本サポート | ? | ? | ? | ? | ? |