在节点学校的一时兴起,我试图用reduce
来计算字符串在数组中重复的次数。
var fruits = ["Apple", "Banana", "Apple", "Durian", "Durian", "Durian"],
obj = {};
fruits.reduce(function(prev, curr, index, arr){
obj[curr] ? obj[curr]++ : obj[curr] = 1;
});
console.log(obj); // {Banana: 1, Apple: 1, Durian: 3}
是有点正在工作。出于某种原因,reduce
似乎跳过了第一个元素。我不知道为什么。它第一次通过数组,index
是1
。我试着加入一些像if (index === 1){//put 'prev' as a property of 'obj'}
这样的逻辑。但这似乎真的很复杂。我确定这不是节点学校希望我解决这个问题的方式。但是,我想知道什么是访问正在减少的数组中的第0个元素的好方法。为什么这个零级元素似乎被还原过程忽略了?我想我可以在回调后传递fruits[0]
所以我最初从那个值开始。访问这个第0个元素的最佳方法是什么?
答案 0 :(得分:11)
如果未提供
initialValue
,则previousValue
将等于数组中的第一个值,currentValue
将等于第二个值。
此外,您必须从函数返回一个值。该值在下一次迭代时变为previousValue
的值。
我建议你“携带”你的聚合器obj
作为初始值。
var fruits = ["Apple", "Banana", "Apple", "Durian", "Durian", "Durian"];
var obj = fruits.reduce(function(carry, fruit){
if(!carry[fruit]) carry[fruit] = 0; // If key doesn't exist, default to 0
carry[fruit]++; // Increment the value of the key
return carry; // Return aggregator for next iteration
}, {});
alert(JSON.stringify(obj));
这是一个简单的图表:
fruit carry (before operation) carry (after operation, returned value)
1st iteration: Apple {} {Apple:1}
2nd iteration: Banana {Apple:1} {Apple:1, Banana:1}
3rd iteration: Apple {Apple:1, Banana:1} {Apple:2, Banana:1}
4th iteration: Durian {Apple:2, Banana:1} {Apple:2, Banana:1, Durian:1}
5th iteration: Durian {Apple:2, Banana:1, Durian:1} {Apple:2, Banana:1, Durian:2}
6th iteration: Durian {Apple:2, Banana:1, Durian:2} {Apple:2, Banana:1, Durian:3}
答案 1 :(得分:1)
reduce()
的语法是:
arr.reduce(callback[, initialValue])
由于您未提供initialValue
,reduce()
会将其作为第一个previousValue
提供给您,然后为剩余的5个项目调用callback
。如果您提供了initialValue
,则reduce()
会为所有6个项目调用callback
。
initialValue
是您正在构建的obj
。但是,您需要以reduce()
的模式使用它。即,不要声明全局obj
。将其作为initialValue
传递。然后,在每次返回时,您必须返回该值的下一个版本。
reduce()
最终将返回最终结果。
var fruits = ["Apple", "Banana", "Apple", "Durian", "Durian", "Durian"];
var result = fruits.reduce(function(previousValue, currentValue, index, array) {
previousValue[currentValue] ? previousValue[currentValue]++ : previousValue[currentValue] = 1;
return previousValue;
}, { } );
console.log(result);
alert(JSON.stringify(result));

答案 2 :(得分:0)
这个问题已经很老了,答案已经明确了。
此外,我还包含了官方文档中的描述,该描述还有其他要点,这将对新来者有帮助
From the official documentation of Array.prototype.reduce()
reduce()方法为每个分配的值执行一次回调 存在于数组中,带有四个参数:
- 蓄能器
- currentValue
- currentIndex
- 数组
第一次调用回调时,累加器和currentValue 可以是两个值之一。如果在调用中提供了initialValue reduce(),则累加器将等于initialValue,并且 currentValue将等于数组中的第一个值。如果不 提供initialValue,则累加器将等于第一个 数组中的值,并且currentValue将等于第二个。
注意:如果未提供initialValue,则reduce()将执行 从索引1开始的回调函数,跳过第一个索引。如果 提供了initialValue,它将从索引0开始。
如果数组为空且未提供initialValue,则TypeError将 被扔。
如果数组只有一个元素(与位置无关)而没有 提供initialValue,或者如果提供initialValue,但数组 为空,将返回solo值,而无需调用回调。
还有一点修改,
var fruits = ["Apple", "Banana", "Apple", "Durian", "Durian", "Durian"], obj = {};
fruits.reduce((prev, curr, index, arr) => {
if(!prev.hasOwnProperty(curr)) {
prev[curr] = 0;
}
prev[curr]++;
return prev;
}, obj);
console.log(obj);