→
その 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。
¶以下を省く