从头开始创建 _.reduce
Creating _.reduce from scratch
我正在尝试从头开始从下划线库重新创建 _.reduce 方法,但我没有通过三个测试用例。 1. 即使迭代器 returns 未定义,也应继续调用迭代器。 2. 如果传入备忘录,应将数组的每一项传递到迭代器。 3. 如果未传入备忘录,应首先将数组的第二项传递到迭代器。我一直在查看文档和我认为 iterator(accumulator, collection[1], 1, collection) 会涵盖第三种情况,但我想不会。
_.reduce = function(collection, iterator, accumulator) {
// TIP: To support both arrays and objects, try re-using each() here
if (accumulator === undefined) {
accumulator = collection[0];
iterator(accumulator, collection[1]);
}
_.each(collection, function(val) {
iterator(accumulator, val);
}
);
return accumulator;
};
一些问题:
如果 accumulator
未定义,您的代码首先使用 collection[1]
调用 iterator
,但如果 collection
不是数组,这将不代表集合的第二个元素。例如,{a:1, b:2}
中的第二个元素将是 collection.b
.
如果 accumulator
未定义,您的代码仍将继续执行 _.each
,这将在集合的第一个元素上调用 iterator
,您想避免...
您的代码忽略了由 iterator
调用编辑的值 return。它应该捕获此 return 值并将其分配给 accumulator
应该使用第三个参数调用 iterator
:值的 index/key。
iterator
应该用第四个参数调用:正在迭代的完整集合
更正:
_.reduce = function(collection, iterator, accumulator) {
_.each(collection, function(val, i) {
if (accumulator === undefined && i === 0) accumulator = val;
else accumulator = iterator(accumulator, val, i, collection);
});
return accumulator;
};
// Tests
console.log(_.reduce([1,2,3], (a, b) => a+b, 1) === 7);
console.log(_.reduce([1,2,3], (a, b) => a+b) === 6);
console.log(_.reduce({a: 1, b: 2, c:3}, (a, b, i) => a+b, 0) === 6);
console.log(_.reduce({a: 1, b: 2, c:3}, (a, b, i) => a+i, "") === "abc");
console.log(_.reduce([], (a, b) => a+b, 0) === 0);
console.log(_.reduce([], (a, b) => a+b) === undefined);
console.log(_.reduce([1,2,3], (a, b, i, all) => a + b * all[i-1]
) === 9);
<script src="https://cdn.jsdelivr.net/npm/underscore@1.13.1/underscore-umd.min.js"></script>
我正在尝试从头开始从下划线库重新创建 _.reduce 方法,但我没有通过三个测试用例。 1. 即使迭代器 returns 未定义,也应继续调用迭代器。 2. 如果传入备忘录,应将数组的每一项传递到迭代器。 3. 如果未传入备忘录,应首先将数组的第二项传递到迭代器。我一直在查看文档和我认为 iterator(accumulator, collection[1], 1, collection) 会涵盖第三种情况,但我想不会。
_.reduce = function(collection, iterator, accumulator) {
// TIP: To support both arrays and objects, try re-using each() here
if (accumulator === undefined) {
accumulator = collection[0];
iterator(accumulator, collection[1]);
}
_.each(collection, function(val) {
iterator(accumulator, val);
}
);
return accumulator;
};
一些问题:
如果
accumulator
未定义,您的代码首先使用collection[1]
调用iterator
,但如果collection
不是数组,这将不代表集合的第二个元素。例如,{a:1, b:2}
中的第二个元素将是collection.b
.如果
accumulator
未定义,您的代码仍将继续执行_.each
,这将在集合的第一个元素上调用iterator
,您想避免...您的代码忽略了由
iterator
调用编辑的值 return。它应该捕获此 return 值并将其分配给accumulator
应该使用第三个参数调用
iterator
:值的 index/key。iterator
应该用第四个参数调用:正在迭代的完整集合
更正:
_.reduce = function(collection, iterator, accumulator) {
_.each(collection, function(val, i) {
if (accumulator === undefined && i === 0) accumulator = val;
else accumulator = iterator(accumulator, val, i, collection);
});
return accumulator;
};
// Tests
console.log(_.reduce([1,2,3], (a, b) => a+b, 1) === 7);
console.log(_.reduce([1,2,3], (a, b) => a+b) === 6);
console.log(_.reduce({a: 1, b: 2, c:3}, (a, b, i) => a+b, 0) === 6);
console.log(_.reduce({a: 1, b: 2, c:3}, (a, b, i) => a+i, "") === "abc");
console.log(_.reduce([], (a, b) => a+b, 0) === 0);
console.log(_.reduce([], (a, b) => a+b) === undefined);
console.log(_.reduce([1,2,3], (a, b, i, all) => a + b * all[i-1]
) === 9);
<script src="https://cdn.jsdelivr.net/npm/underscore@1.13.1/underscore-umd.min.js"></script>