a
배열 요소에 대한 연관 작업 f
의 경우 다음과 같은 관계가 유지되어야합니다. a.reduce(f)
은 a.reduceRight(f)
과 같아야합니다.JavaScript에서 reduceRight의 네이티브 구현이 잘못되었습니다.
실제로 연관성과 교환 성 모두의 연산에 대해서는 사실입니다. 예를 들어 :
var a = [1,2,3,4,5,6,7,8,9,0];
alert(a.reduce(add) === a.reduceRight(add));
function add(a, b) {
return a + b;
}
var a = [[1,2],[3,4],[5,6],[7,8],[9,0]];
alert(equals(a.reduce(concat), a.reduceRight(concat)));
function concat(a, b) {
return a.concat(b);
}
function equals(a, b) {
var length = a.length;
if (b.length !== length) return false;
for (var i = 0; i < length; i++)
if (a[i] !== b[i]) return false;
return true;
}
우리는 reduceRight
에 대한 f
의 인수를 뒤집어 야하는 것은 그들이 동등한 만들려면 :
var a = [[1,2],[3,4],[5,6],[7,8],[9,0]];
alert(equals(a.reduce(concat), a.reduceRight(concatRight)));
function concat(a, b) {
return a.concat(b);
}
function concatRight(b, a) {
return a.concat(b);
}
function equals(a, b) {
var length = a.length;
if (b.length !== length) return false;
for (var i = 0; i < length; i++)
if (a[i] !== b[i]) return false;
return true;
}
이 날 것을 믿을 수 있습니다의 기본 구현이 잘못되었습니다. 그것은 그것을 함수 f
번째 파라미터를 확인하는 것이 합리적 right
이후
var REDUCE_ERROR = "Reduce of empty array with no initial value";
Array.prototype.reduceRight = function (f, acc) {
var a = this, length = a.length;
if (arguments.length < 2) {
if (length !== 0) var right = a[--length];
else throw new TypeError(REDUCE_ERROR);
} else var right = acc;
while (length !== 0) right = f(a[--length], right, length, a);
return right;
};
이전 값 (우측 값)을 나타낸다 :
는 I는 다음과 같이 reduceRight
기능이 구현되어야한다고 판단 . 현재 값은 왼쪽 값을 나타냅니다. 따라서 현재 값을 함수의 첫 번째 매개 변수 인 f
으로 만드는 것이 좋습니다. 이러한 방식으로, 비 - 교환 적 연상 작용에 대해서조차도, 앞서 언급 한 관계가 성립한다.
그래서, 내 질문은 :
- 는 않습니다되지는 참으로 내가 한 방식으로 구현 될
reduceRight
에 대한 더 많은 이해가? - 이유는 무엇입니까?
reduceRight
은 내가했던 것처럼 구현되지 않았습니까?
이하지 않다고해서 [ 'foldr'와'foldl'] (http://en.wikipedia.org/wiki/Fold_ (higher-order_function))은 다른 방향에서 작동합니까? 그것이 둘 다 갖는 점이며, 비 교환 적 연산은 필연적으로 다른 결과를 반환합니다. – ssube
@ssube 그들은 다른 방향으로 작동 할 수 있지만 연관 연산에 대해 동일한 결과를 반환해야합니다. 예를 들어 :'foldl1 (++) xs == foldr1 (++) xs'는 하스켈에서'True'입니다. –