f
array の要素に対する連想操作のa
場合、次の関係が成り立つ必要があります:a.reduce(f)
は と同等である必要がありますa.reduceRight(f)
。
実際、それは結合的かつ交換可能な操作にも当てはまります。例えば:
const a = [0,1,2,3,4,5,6,7,8,9];
const add = (a, b) => a + b;
console.log(a.reduce(add));
console.log(a.reduceRight(add));
ただし、結合的ではあるが可換的ではない操作には当てはまりません。例えば:
const a = [[0,1],[2,3],[4,5],[6,7],[8,9]];
const concat = (a, b) => a.concat(b);
console.log(JSON.stringify(a.reduce(concat)));
console.log(JSON.stringify(a.reduceRight(concat)));
f
forの引数を反転reduceRight
させて同等にする必要があります。
const a = [[0,1],[2,3],[4,5],[6,7],[8,9]];
const concat = (a, b) => a.concat(b);
const concatRight = (b, a) => a.concat(b);
console.log(JSON.stringify(a.reduce(concat)));
console.log(JSON.stringify(a.reduceRight(concatRight)));
reduceRight
これは、のネイティブ実装が間違っていると私に信じさせます。
reduceRight
この機能は次のように実装する必要があると思います。
var REDUCE_ERROR = "Reduce of empty array with no initial value";
Array.prototype.reduceRight = function (f, acc) {
let { length } = this;
const noAcc = arguments.length < 2;
if (noAcc && length === 0) throw new TypeError(REDUCE_ERROR);
let result = noAcc ? this[--length] : acc;
while (length > 0) result = f(this[--length], result, length, this);
return result;
};
result
は前の値 (右側の値) を表すため、関数の 2 番目のパラメーターにするのが理にかなっていますf
。現在の値は左側の値を表します。したがって、現在の値を関数の最初のパラメーターにすることは理にかなっていますf
。このように、可換でない連想操作の場合でも、前述の関係が成り立ちます。
だから、私の質問は次のとおりです。
reduceRight
私が行った方法で実装する方が理にかなっているのではありませんか?- ネイティブが
reduceRight
私のように実装されないのはなぜですか?