我看到reduce 正在传递一个匿名函数而不是combine 函数
这不是真的。匿名函数is the combine
功能。
combine(base, element)
vs function(total, element)
这两个函数调用本质上彼此相同:combine(base,element) 和 function(total,element)?
不,它们是完全不同的东西。
前者是函数调用,指向由combine
.
然而,第二个计算结果为新的函数值。如果是:
reduce(function(total, element) {...}, ...);
reduce()
正在传递一个函数值,这意味着,新功能 is created,一个接受两个参数的函数(表示为total
and element
)。然后这个函数被传递给reduce
.
让我回顾一下昨天的可视化。重要的是要认识到,这不仅适用于你的情况,但它适用于every的实施例减少(左)概念。
return value of reduce()
/
etc ...
/
combine
/ \
combine xs[2]
/ \
combine xs[1]
/ \
0 xs[0]
当然,这仅表明what发生,而不是how我认为在你的情况下你要求how。只要记住这个可视化,看看结果会怎样。
替换函数
为了更清楚地说明发生了什么,我将逐渐替换正在传递的函数。
程序开始:
function countZeroes(array) {
return count(equals(0), array);
}
equals(0)
(您可以将其称为柯里化的一种形式)计算为一个函数,该函数被传递给count()
.
这基本上导致以下结果count()
功能:
function count(array) {
return reduce(function(total, element) { // Where is the value for total coming from?
return total + (0 == element ? 1 : 0);
}, 0, array);
}
从这里,我们可以提取combine
争论:
function combine(total, element) { // Where is the value for total coming from?
return total + (0 == element ? 1 : 0);
}
这是在reduce 函数中使用的函数:
function reduce(base = 0, array) {
forEach(array, function (element) {
base = combine(base, element);
});
return base;
}
reduce(0, array)
被称为来自count()
功能。传递给的函数forEach
现在可以像这样重写,考虑到我们的实现combine
:
function reduce(base = 0, array) {
forEach(array, function (element) {
base = base + (0 == element ? 1 : 0);
});
return base;
}
请记住,base
代表我们的total
.
作为我们的最后一步,我们考虑什么forEach()
does.
function reduce(base = 0, array) {
for (var i = 0; i < array.length; i++)
base = base + (0 == array[i] ? 1 : 0);
}
return base;
}
所以这就是count()
基本上看起来像,所有调用都已展开:
function count(array) {
var base = 0;
for (var i = 0; i < array.length; i++)
base = base + (0 == array[i] ? 1 : 0);
}
return base;
}