有人可以解释这是如何运作的。
学习使用 Array.reduce()
var votes = ['tacos','pizza','pizza','tacos','fries','ice cream','ice cream','pizza'];
var initialValue = {}
var reducer = function(tally, vote) {
if (!tally[vote]) {
tally[vote] = 1;
} else {
tally[vote] = tally[vote] + 1;
}
return tally;
}
var result = votes.reduce(reducer, initialValue)
答案 0 :(得分:3)
reduce的工作方式与map
或filter
非常相似。在这种情况下,reducer负责将对象数组减少到一个对象中。
reducer函数遍历数组的所有元素。该函数使用两个参数调用,tally
- 到目前为止减少的结果和vote
- 当前正在处理的数组元素。
如果tally
没有像当前正在处理/缩小的元素那样命名的属性,它会向对象添加这样的键并将其值设置为1。否则(密钥存在),它会增加1。
有关详细信息,请转到here
答案 1 :(得分:1)
基本上Array.prototype.reduce()
方法对累加器和数组的每个值应用一个函数,以将其减少为单个值。
在您的示例中,缩减值(计数操作的结果)被指定为tally
返回的名为.reduce()
的对象的属性;
我评论你的简短解释:
// your data in an array
var votes = ['tacos','pizza','pizza','tacos','fries','ice cream','ice cream','pizza'];
// optional value to use as the first argument to the first call of the callback when using Array.prototype.reduce().
var initialValue = {}
// tally = previousValue and vote = currentValue
var reducer = function(tally, vote) {
// if tally is not assign as a key in tally object, add key and add value of one, (basically count 1 for one element in your votes array)
if (!tally[vote]) {
tally[vote] = 1;
} else {
// otherwise if tally object has already this key, increment its value by one, (basically it counts how many times each item in votes array is present in the array)
tally[vote] = tally[vote] + 1;
}
return tally;
}
var result = votes.reduce(reducer, initialValue);
console.log(result);
注意:您实际上可以避免使用为initialValue
声明变量而只使用var result = votes.reduce(reducer, {});
API文档:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce
更多示例和简要说明:
答案 2 :(得分:1)
我在您的代码中插入了一些console.log消息,这有助于我了解发生了什么。
var votes = ['tacos', 'pizza', 'pizza', 'tacos', 'fries', 'ice cream', 'ice cream', 'pizza'];
var initialValue = {}
var reducer = function(tally, vote) {
console.log("tally: ", tally);
console.log("vote: ", vote);
console.log("tally[vote]: ", tally[vote]);
if (!tally[vote]) {
tally[vote] = 1;
} else {
tally[vote] = tally[vote] + 1;
}
return tally;
}
var result = votes.reduce(reducer, initialValue)
console.log("result: " + JSON.stringify(result));

答案 3 :(得分:1)
这里和其他地方有reduce
的大量详细解释,但我认为简单的视觉演示可能会有所帮助
[1,2,3].reduce(function(a,b) { return a + b }, 0)
// (((0 + 1) + 2) + 3)
// => 6
你可以看到:
reduce
至于你的代码,我们没有构建数字的总和,我们正在构建一个 Object ,它保存数组中每个字符串的计数。
我没有必要解释其他人的所作所为,但这并不奇怪,这可能让你感到困惑,因为没有人解释这是滥用对象。
事实上,对象实际上并不是这种减少的最佳数据结构选择。这里,Object用于模拟Map的行为。
我们会将initialValue
设置为new Map()
,您会看到reducer
如何使用更具描述性的语法。注意注释甚至不是必需的,因为代码说明了它需要的所有内容。
var votes = ['tacos','pizza','pizza','tacos','fries','ice cream','ice cream','pizza']
var initialValue = new Map()
var reducer = function (tally, vote) {
if (tally.has(vote))
return tally.set(vote, tally.get(vote) + 1)
else
return tally.set(vote, 1)
}
var result = votes.reduce(reducer, initialValue)
console.log(Array.from(result.entries()))
输出
[
[ "tacos", 2 ],
[ "pizza", 3 ],
[ "fries", 1 ],
[ "ice cream", 2 ]
]
我可以通过编写构建字符串的reducer而不是实际添加数字来表明通过reduce的总和的可视化表示是正确/准确的
var initialValue = 0
var reducer = function(a,b) { return '(' + a + ' + ' + b + ')' }
var result = [1,2,3].reduce(reducer, initialValue)
console.log(result)
// (((0 + 1) + 2) + 3)
在尝试理解/调试自己的Reducer时,此技术可能对您有用
答案 4 :(得分:0)
reduce()方法将数组降低为单个值。
reduce()方法执行 提供的函数,用于数组的每个值(来自左到右强>)。
该函数的返回值在累加器中存储(结果/总计)。
您有给定列表:
var votes = ['tacos','pizza','pizza','tacos','fries','ice cream','ice cream','pizza'];
然后你制作一个初始列表。 您可以修改此功能,该功能将应用于两个列表。
var initialValue = {}
"减速器"被初始化为函数。 我们将函数放在" reducer"中的原因是这样我们可以更容易地进一步调用它。您可以在此功能中执行任何操作,并且将在后续步骤中的列表中执行
var reducer = function(tally, vote) {
if (!tally[vote]) {
tally[vote] = 1;
} else {
tally[vote] = tally[vote] + 1;
}
return tally;
}
最后,该功能的结果 存储到变量中。
var result = votes.reduce(reducer, initialValue)
答案 5 :(得分:0)
好吧,让我们尝试扩展迭代:
执行时
votes.reduce(reducer, initialValue)
它实际上是这样做的:
reducer(initialValue, votes[0]); // step1, return {'tacos': 1}
reducer(returnedValueOfStep1, votes[1]); // step2, return {'tacos': 1, 'pizza': 1}
reducer(returnedValueOfStep2, votes[2]); // step3, return {'tacos': 1, 'pizza': 2}
reducer(returnedValueOfStep3, votes[3]); // step4 ...
reducer(returnedValueOfStep4, votes[4]); // step5 ...
reducer(returnedValueOfStep5, votes[5]); // step6 ...
reducer(returnedValueOfStep6, votes[6]); // step7 ...
reducer(returnedValueOfStep7, votes[7]); // step8 ...
我现在很清楚。
通常,如果我们不提供initialValue作为reduce的第二个参数,它将把数组的第一个元素作为initialValue,并从第二个元素开始迭代:
reducer(votes[0], votes[1]); // step1 ...
reducer(returnedValueOfStep1, votes[2]); // step2 ...
...