→
その Array の後方からコールバック関数に掛けて戻り値をアキュームレーターとし、結果の値(アキュームレーター)を返します。
最初のコールバック関数で、初期値initialValueが指定されていればそれがアキュームレーターaccumulatorとしてセットされ、指定されていなければ配列の最後がアキュームレーターの値としてセットされ、処理が行われます。
コールバック関数による:
function 関数名(accumulator, element[, index[, array]]){
処理
}
インラインコールバック関数による:
アロー関数による:
| 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) {
// …
});
関数が初めて呼び出されたとき、accumulator と element は、2 つの値のいずれかになります。reduceRight の呼び出しで initialValue が指定された場合、accumulator は initialValue と等しくなり、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。
¶以下を省く