Join MDN and developers like you at Mozilla's View Source conference, 12-14 September in Berlin, Germany. Learn more at https://viewsourceconf.org

Array.prototype.reduce()

概要

隣り合う 2 つの配列要素に対して(左から右へ)同時に関数を適用し、単一の値にします。

構文

var result = array.reduce(callback[, initialValue]);

引数

callback
4 つの引数を取って、配列内の各値に対し実行するコールバック関数
previousValue
現在処理されている配列要素の 1 つ前の要素。もしくは、initialValueinitialValue については、後で述べます。
currentValue
現在処理されている配列要素
index
現在処理されている配列要素のインデックス
array
reduce に呼ばれた配列
initialValue
callback の最初の呼び出しのときに、最初の実引数として用いるためのオブジェクト。

詳細

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 に基づく。

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

関連情報

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

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