Array.prototype.reduceRight()

概要

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

構文

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

引数

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

詳細

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

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

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

関数が呼び出される初回は、 previousValuecurrentValue は 2 つの値のうちの 1 つを取り得ます。reduce 呼び出し時に、initialValue が与えられた場合、previousValueinitialValue と等しくなり、currentValue は、配列の最後の値と等しくなります。 initialValue が与えられなかった場合、previousValue は配列の最後の値と等しくなり、currentValue は、最後から数えて 2 番目の値と等しくなります。

関数の実行を追った様子の例は、以下のようになるでしょう。

[0,1,2,3,4].reduceRight(function(previousValue, currentValue, index, array){
  return previousValue + currentValue;
});

// 最初の呼び出し
previousValue = 4, currentValue = 3, index = 3

// 2 回目の呼び出し
previousValue = 7, currentValue = 2, index = 2

// 3 回目の呼び出し
previousValue = 9, currentValue = 1, index = 1

// 4 回目の呼び出し
previousValue = 10, currentValue = 0, index = 0

// array は、常に、reduce が呼び出された [0,1,2,3,4] というオブジェクトです。

// 戻り値: 10

initialValue を与えた場合、その結果は、以下のようになるでしょう。

[0,1,2,3,4].reduceRight(function(previousValue, currentValue, index, array){
  return previousValue + currentValue;
}, 10);

// 最初の呼び出し
previousValue = 10, currentValue = 4, index = 4

// 2 回目の呼び出し
previousValue = 14, currentValue = 3, index = 3

// 3 回目の呼び出し
previousValue = 17, currentValue = 2, index = 2

// 4 回目の呼び出し
previousValue = 19, currentValue = 1, index = 1

// 5 回目の呼び出し
previousValue = 20, currentValue = 0, index = 0

// array は、常に、reduce が呼び出された [0,1,2,3,4] というオブジェクトです。

// 戻り値: 20

互換性

reduce は、ECMA-262 第 5 版に追加された仕様であり、他の標準の実装には存在しない場合があります。以下のコードをスクリプトの先頭に挿入することにより、ネイティブでの実装の如何に関わらずこれを動作させる事ができます。このアルゴリズムは ECMA-262 第 5 版で指示されたアルゴリズムと全く同じものです。ObjectTypeError はそれぞれオリジナルの値を持ち、またそれらの callbackfn.callFunction.prototype.call のオリジナルの値として評価されます。

if (!Array.prototype.reduceRight) {
  Array.prototype.reduceRight = function(callbackfn /*, initialValue */) {
    "use strict";

    if (this == null) throw new TypeError();

    var t = Object(this);
    var len = t.length >>> 0;

    if (typeof callbackfn != "function") throw new TypeError();

    // no value to return if no initial value, empty array
    if (len === 0 && arguments.length === 1) throw new TypeError();

    var k = len - 1;
    var accumulator;
    if (arguments.length >= 2) {
      accumulator = arguments[1];
    } else {
      do {
        if (k in this) {
          accumulator = this[k--];
          break;
        }

        // if array contains no values, no initial value to return
        if (--k < 0) throw new TypeError();
      } while (true);
    }

    while (k >= 0) {
      if (k in t) accumulator = callbackfn.call(undefined, accumulator, t[k], k, t);
      k--;
    }

    return accumulator;
  };
}

例: 配列内の値を全て足す

var total = [0, 1, 2, 3].reduceRight(function(a, b) {
    return a + b;
});
// total == 6

例: 二次元配列を一次元配列にする

var flattened = [[0, 1], [2, 3], [4, 5]].reduceRight(function(a, b) {
    return a.concat(b);
}, []);
// flattened is [4, 5, 2, 3, 0, 1]

ブラウザ実装状況

Kangax's compat tables に基づく。

機能 Chrome Firefox (Gecko) Internet Explorer Opera Safari
基本サポート (有) 3.0 (1.9) 9 10.5 4.0
機能 Android Chrome for Android Firefox Mobile (Gecko) IE Mobile Opera Mobile Safari Mobile
基本サポート ? ? ? ? ? ?

関連情報

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

Contributors to this page: teoli, ethertank, Mgjbot, Potappo
最終更新者: teoli,
サイドバーを隠す