この翻訳は不完全です。英語から この記事を翻訳 してください。

reduceRight()は、隣り合う 2 つの配列要素に対して(右から左へ)同時に関数を適用し、単一の値にします。
 
 
左から右へ適用する際は Array.prototype.reduce() を参照してください。

構文

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

引数

callback
4 つの引数を取って、配列内の各値に対し実行するコールバック関数
accumulator
現在処理されている配列要素の 1 つ前の要素。もしくは、initialValueinitialValue については、以下に記述します。
currentValue
現在処理されている配列要素
indexOptional
現在処理されている配列要素のインデックス
arrayOptional
reduceRight によって呼ばれる配列
initialValueOptional
callback の最初の呼び出しのときに、最初の実引数として用いるためのオブジェクト。initialValueが渡されなかった際は、配列の最後の要素が適用されます。また、空の配列に対して、初期値なしで呼び出すとエラーとなります。

戻り値

The value that results from the reduction.

詳細

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

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

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

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

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

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

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

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

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

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

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

// 戻り値: 10

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

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

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

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

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

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

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

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

// 戻り値: 20

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

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]

 

Run a list of asynchronous functions with callbacks in series each passing their results to the next

const waterfall = (...functions) => (callback, ...args) =>
  functions.reduceRight(
    (composition, fn) => (...results) => fn(composition, ...results),
    callback
  )(...args);

const randInt = max => Math.floor(Math.random() * max)

const add5 = (callback, x) => {
  setTimeout(callback, randInt(1000), x + 5);
};
const mult3 = (callback, x) => {
  setTimeout(callback, randInt(1000), x * 3);
};
const sub2 = (callback, x) => {
  setTimeout(callback, randInt(1000), x - 2);
};
const split = (callback, x) => {
  setTimeout(callback, randInt(1000), x, x);
};
const add = (callback, x, y) => {
  setTimeout(callback, randInt(1000), x + y);
};
const div4 = (callback, x) => {
  setTimeout(callback, randInt(1000), x / 4);
};

const computation = waterfall(add5, mult3, sub2, split, add, div4);
computation(console.log, 5) // -> 14

// same as:

const computation2 = (input, callback) => {
  const f6 = x=> div4(callback, x);
  const f5 = (x, y) => add(f6, x, y);
  const f4 = x => split(f5, x);
  const f3 = x => sub2(f4, x);
  const f2 = x => mult3(f3, x);
  add5(f2, input);
}

Difference between reduce and reduceRight

var a = ['1', '2', '3', '4', '5']; 
var left  = a.reduce(function(prev, cur)      { return prev + cur; }); 
var right = a.reduceRight(function(prev, cur) { return prev + cur; }); 

console.log(left);  // "12345"
console.log(right); // "54321"

 

 

互換性

reduceRight は、ECMA-262 第 5 版に追加された仕様であり、他の標準の実装には存在しない場合があります。以下のコードをスクリプトの先頭に挿入することにより、ネイティブでの実装の如何に関わらずreduceRightを動作させる事ができます。

// Production steps of ECMA-262, Edition 5, 15.4.4.22
// Reference: http://es5.github.io/#x15.4.4.22
if ('function' !== typeof Array.prototype.reduceRight) {
  Array.prototype.reduceRight = function(callback /*, initialValue*/) {
    'use strict';
    if (null === this || 'undefined' === typeof this) {
      throw new TypeError('Array.prototype.reduce called on null or undefined');
    }
    if ('function' !== typeof callback) {
      throw new TypeError(callback + ' is not a function');
    }
    var t = Object(this), len = t.length >>> 0, k = len - 1, value;
    if (arguments.length >= 2) {
      value = arguments[1];
    } else {
      while (k >= 0 && !(k in t)) {
        k--;
      }
      if (k < 0) {
        throw new TypeError('Reduce of empty array with no initial value');
      }
      value = t[k--];
    }
    for (; k >= 0; k--) {
      if (k in t) {
        value = callback(value, t[k], k, t);
      }
    }
    return value;
  };
}

策定

策定 状況 備考
ECMAScript 5.1 (ECMA-262)
Array.prototype.reduceRight の定義
標準 初期定義。JavaScript 1.8にて実装。
ECMAScript 2015 (6th Edition, ECMA-262)
Array.prototype.reduceRight の定義
標準  
ECMAScript Latest Draft (ECMA-262)
Array.prototype.reduceRight の定義
ドラフト  

ブラウザ実装状況

 

Update compatibility data on GitHub
デスクトップモバイルサーバー
ChromeEdgeFirefoxInternet ExplorerOperaSafariAndroid webviewAndroid 版 ChromeEdge MobileAndroid 版 FirefoxAndroid 版 OperaiOSのSafariSamsung InternetNode.js
基本対応Chrome 完全対応 ありEdge 完全対応 ありFirefox 完全対応 3IE 完全対応 9Opera 完全対応 10.5Safari 完全対応 4WebView Android 完全対応 ありChrome Android 完全対応 ありEdge Mobile 完全対応 ありFirefox Android 完全対応 4Opera Android 完全対応 ありSafari iOS 完全対応 ありSamsung Internet Android 完全対応 ありnodejs 完全対応 あり

凡例

完全対応  
完全対応

関連情報

 

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

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