JavaScript

Array.prototype.reduceRight()メソッド

 編集:2022.08.18 by T.A.

その Array の後方からコールバック関数に掛けて戻り値をアキュームレーターとし、結果の値(アキュームレーター)を返します。

最初のコールバック関数で、初期値initialValueが指定されていればそれがアキュームレーターaccumulatorとしてセットされ、指定されていなければ配列の最後がアキュームレーターの値としてセットされ、処理が行われます。

コールバック関数による:

arr.reduceRight(callback[, initialValue])
関数:
function 関数名(accumulator, element[, index[, array]]){
 処理
}

インラインコールバック関数による:

arr.reduceRight(function(accumulator, element[, index[, array]]){処理}[, initialValue])

アロー関数による:

arr.reduceRight( (accumulator, element[, index[, array]]) => {処理}[, initialValue])
arr Arrayオブジェクト
callback 関数名を記述。
関数名 callbackと同じ名前を記述。
処理 処理プログラム。必ずreturnで処理結果を返す必要があり、それがアキュームレーターとなり次の処理に使われます。

アロー関数使用の場合、「{ }」に囲まれていない場合は評価式となります。

accumulator 現在のアキュームレーターの値。コールバック関数に入るときに最後の要素の値がセットされ、initialValueが設定されている場合はその値がセットされます。
element 現在処理されている配列要素
index 省略可。現在処理されている配列要素のインデックス。

コールバック関数に入った最初は arr.length-1-1 となり、initialValueが設定されている場合は arr.length-1 つまり最後の要素の位置となります。

array 省略可。reduceRight() によって呼ばれる配列
initialValue 省略可。コールバック関数に入るときに最初にアキュームレーターにセットする値。¶オブジェクト?。省いた場合は配列の最後の要素がアキュームレーターにセットされます。

また、空の配列に対して、初期値なしで呼び出すと TypeError になります。

戻り値

処理結果で得られたアキュームレーターの値です。

解説

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

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

D=array.reduceRight(function(accumulator, element, index, array) {
  // …
});

関数が初めて呼び出されたとき、accumulatorelement は、2 つの値のいずれかになります。reduceRight の呼び出しで initialValue が指定された場合、accumulatorinitialValue と等しくなり、element は配列の最後の値と等しくなります。initialValue が指定されなかった場合、accumulator は配列の最後の値に等しく、element は最後から 2 番目の値に等しくなります。

配列が空で、initialValue が指定されていない場合、TypeError が投げられます。配列に要素が 1 つしかなく(位置に関係なく)、initialValue が指定されていない場合、または initialValue が指定されているが配列が空の場合、callback を呼び出さずに単独の値が返されます。

¶省く

配列内のすべての値を合計する
var sum = [0, 1, 2, 3].reduceRight(function(a, b) {
  return a + b;
}); //=6
配列中の配列を平坦化する
var flattened = [[0, 1], [2, 3], [4, 5]].reduceRight(function(a, b) {
    return a.concat(b);
}, []); //=[4, 5, 2, 3, 0, 1]
一連のコールバックを使用して非同期関数のリストを実行し、それぞれの結果を次のコールバックに渡す
//コンソールにて
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);
}
D=[10,20,30,40].reduceRight(function(Acc, CV, Idx){
  alert(Idx+":"+Acc);
  return Acc+CV;
}); //=100

処理は後方から処理されるようだ。

処理が開始されると最初に最後の要素(インデックス3)がアキュームレーターとしてセットされ、次の要素(インデックス2)から始まる。そしてインデックス1、インデックス0。

D=[10,20,30,40].reduceRight(function(Acc, CV, Idx){
  alert(Idx+":"+Acc);
  return Acc+CV;
},100); //=100

同様に処理は後方から処理されるようだ。

処理が開始されると初期値として100がアキュームレーターにセットされ、最初に最後の要素(インデックス3)から処理される。次にインデックス2、インデックス1、インデックス0。

¶以下を省く


テスト