概要

reduce() はアキュムレータと配列の各要素に対して(左から右へ)関数を適用し、単一の値にします。

構文

array.reduce(callback[, initialValue]);

引数

callback
4 つの引数を取って、配列内の各値に対し実行するコールバック関数
accumulator
コールバックの戻り値を累積します。ひとつ前の処理結果または initialValue を指します。initialValue については、後で述べます。
currentValue
現在処理されている配列要素
index
現在処理されている配列要素のインデックス
array
reduce に呼ばれた配列
initialValue
callback の最初の呼び出しのときに、最初の引数として使用されます。設定しなかった場合、配列の最初の要素が使用されます。空の配列を initialValue なしで実行するとエラーになります。

詳細

reduce は、配列に存在するおのおのの要素に対して、callback 関数を一度だけ実行します。配列における穴は対象からはずされ、また callback 関数は 「初期値(あるいは、直前の callback 呼び出し)」、「現在の要素の値」、「現在のインデックス」、「繰り返しが行われる配列」 の 4 つの引数を受け取ります。

reduce の callback の呼び出しは、以下のように見えるでしょう。:

arrayObj.reduce(function(previousValue, currentValue, index, array){
  // ...
})

関数が呼び出される初回は、 previousValuecurrentValue は 2 つの値のうちの 1 つを取り得ます。reduce 呼び出し時に、initialValue が与えられた場合、previousValueinitialValue と等しくなり、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 に基づく。

We're converting our compatibility data into a machine-readable JSON format. This compatibility table still uses the old format, because we haven't yet converted the data it contains. Find out how you can help!

機能 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
基本サポート ? ? ? ? ?

関連情報

ドキュメントのタグと貢献者

 このページの貢献者: uknmr, teoli, ethertank, Mgjbot, Potappo
 最終更新者: uknmr,