理解 Eloquent Javascript 的 Reduce 功能 [英] Understanding Eloquent Javascript's Reduce function
问题描述
在 Eloquent Javascript 中,作者要求读者编写一个函数 countZeroes
,该函数以一个数字数组作为参数,并返回出现在它是使用 reduce 函数的另一个例子.
In Eloquent Javascript, the author asks the reader to write a function countZeroes
, which takes an array of numbers as its argument and returns the amount of zeroes that occur in it as another example for the use of the reduce function.
我知道
- reduce 函数的概念是获取一个数组并将其转换为单个值.
- 三元运算符正在做什么,这是函数的基本部分.
我不知道
- counter 函数的参数来自哪里.
- where the arguments for the counter function are coming from.
来自书中:
function countZeroes(array) {
function counter(total, element) { // Where are the parameter values coming from?
return total + (element === 0 ? 1 : 0);
}
return reduce(counter, 0, array);
}
来自文本的前面示例:
function reduce(combine, base, array) {
forEach(array, function (element) {
base = combine(base, element);
});
return base;
}
推荐答案
看代码,只有一个可能的答案:因为你的函数 counter
在传递给 reduce()
,因此reduce 必须为函数提供参数.
Looking at the code, there is only one possible answer: Since you the function counter
is only referenced once when passed to reduce()
, reduce must thus provide the arguments to the function.
这是 reduce 工作原理的可视化.需要从上到下看图,/
和\
表示上面的counter()
函数传递了哪些参数(下图).
Here is a visualization of how reduce works. You need to read the diagrom from top to bottom, /
and \
denote which parameters (below) are passed to the counter()
function above.
return value of reduce()
/
etc ...
/
counter
/ \
counter xs[2]
/ \
counter xs[1]
/ \
0 xs[0]
counter()
最初提供了 0
(毕竟,当你还没有处理任何元素时,看到的零的初始总量只是零)和第一个元素.
counter()
is initially provided with 0
(after all, the initial total amount of seen zeroes when you haven't processed any elements yet is just zero) and the first element.
如果数组的第一个元素是零,则 0
增加 1.看到第一个元素后的新总数然后由 counter(0, xs[0])
返回给 reduce()
函数.只要元素还剩下,它就会将此值作为新的待处理总数与数组中的下一个元素一起传递给 counter()
函数:xs[1]
.
That 0
is increased by one if the first element of the array is a zero. The new total after having seen the first element is then returned by counter(0, xs[0])
to the reduce()
function. As long as elements are left, it then passes this value as new pending total to the counter()
function, along with the next element from your array: xs[1]
.
只要数组中有元素就重复这个过程.
This process is repeated as long as there are elements in the array.
function reduce(combine, base, array) {
forEach(array, function (element) {
base = combine(base, element);
});
return base;
}
从图中可以看出,0
最初是通过 base
和 element
一起传递给函数的,element
表示 xs[0]
在 forEach
构造中的第一个迭代"上.然后将结果值写回 base
.
As can be seen in the illustration, 0
is passed through base
to the function initially, along with element
, which denotes xs[0]
on the first "iteration" within the forEach
construct. The resulting value is then written back to base
.
正如您在可视化中看到的,0
是函数 counter()
的左参数,然后其结果作为左参数传递给 counter()
.由于 base/total
在 forEach
构造中充当左参数,因此将该值写回 base/total
是有意义的,因此之前的结果将在下一次迭代时再次传递给 counter()/combine()
./
s的路径就是base/total
的流".
As you can see in the visualization, 0
is the left parameter to the function counter()
, whose result is then passed as left parameter to counter()
. Since base/total
acts as the left paramter within the forEach
construct, it makes sense to write that value back to base/total
, so the previous result will be passed to counter()/combine()
again upon the next iteration. The path of /
s is the "flow" of base/total
.
来自 Eloquent JavaScript 的第 6 章,这里是 forEach()
的实现(在评论,我已经用最终值替换了对 action
的调用.)
From chapter 6 of Eloquent JavaScript, here is the implementation of forEach()
(In the comment, I have substituted the call to action
with the eventual values.)
function forEach(array, action) {
for (var i = 0; i < array.length; i++)
action(array[i]); // <-- READ AS: base = counter(base, array[i]);
}
action
表示一个函数,它在一个简单的 for
循环中为每个元素调用,同时遍历 array
.
action
denotes a function, that is called within a simple for
loop for every element, while iterating over array
.
在您的情况下,这作为 action
传递给 forEach()
:
In your case, this is passed as action
to forEach()
:
function (element) {
base = combine(base, element);
}
它是在每次调用 reduce()
时定义的匿名函数.因此,对于 for
的每次迭代,element
是真正的"array[i]
一次.
It is the anonymous function defined upon each call to reduce()
. So element
is "really" array[i]
once for each iteration of the for
.
这篇关于理解 Eloquent Javascript 的 Reduce 功能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!