Javascript 如何减少这里的工作量?
我正在阅读javascript中reduce函数的文档,我被这个示例卡住了Javascript 如何减少这里的工作量?,javascript,reduce,Javascript,Reduce,我正在阅读javascript中reduce函数的文档,我被这个示例卡住了 var names = ['Alice', 'Bob', 'Tiff', 'Bruce', 'Alice']; var countedNames = names.reduce(function(allNames, name) { if (name in allNames) { allNames[name]++; } else { allNames[name] = 1;
var names = ['Alice', 'Bob', 'Tiff', 'Bruce', 'Alice'];
var countedNames = names.reduce(function(allNames, name) {
if (name in allNames) {
allNames[name]++;
} else {
allNames[name] = 1;
}
return allNames;
}, {});
console.log(countedNames);
它如何输出:
{'Alice':2,'Bob':1,'Tiff':1,'Bruce':1}
而不是
{2,1,1,1}
因此
reduce
将获取一个数组
,并将其减少为一个值。在您的例子中,您正在将数组
中的名称减少为一个哈希,该哈希包含名称以及该名称在数组中存在的次数。reduce
的最后一个参数是初始起始值。在这种情况下,您给它一个空的对象
。此对象
由回调函数中的所有名称
表示。因此,对于数组中的每个名称
,如果该名称
已经存在,请签入所有名称
。如果是,则增加该名称的计数
,否则将其设置为1
reduce函数以一个起始值开始,随后传入数据的“reduces”将提供修改。在这种情况下,起始值是{}
,即从代码的最后第二行开始的对象文本。在本例中,将应用所有新修改的逐渐累积值称为allNames
。当reduce
函数对allNames[name]
执行某些操作时,它正在对键为name
的allNames
对象的属性执行某些操作,例如'Alice'
。因此,例如,第一次遇到Alice的名字时,将创建键为Alice
的属性,并将其赋值为1
。这将继续执行原始输入,最终生成您指定的最终结果。数组。prototype.reduce()
是一个累加器函数-它将迭代数组中的所有元素,并对它们执行一些操作,以将它们减少为单个值。在本例中,我们将单个值初始化为空对象,allnames={}
。在遍历这些名称时,我们检查该名称是否已作为键存在于对象中-如果已存在,则增加计数,如果未存在,则将该键值对初始化为:1
:
var names = ['Alice', 'Bob', 'Tiff', 'Bruce', 'Alice'];
var countedNames = names.reduce(function(allNames, name) {
if (name in allNames) { //first time through, allNames = {}
allNames[name]++; //if name is present as key in allNames object, increment the value by 1
} else {
allNames[name] = 1; //first time through now allNames = {'Alice': 1 }
}
return allNames;
}, {}); //initialize allNames with empty object
您正在向reduce方法传递一个匿名函数和一个空对象。如果您查看MDN上关于reduce的文档:
您可以看到它接受回调函数和初始值。在这种情况下,您将传递一个空对象{}
作为初始值(请参见倒数第二行)
然后,reduce
方法“对累加器和数组的每个值(从左到右)应用一个函数,将其减少为单个值。”
这个值以空对象的值开始,然后根据回调函数体中的条件逻辑在此对象中添加和递增属性
您的线路:
allNames[name] = 1
用于创建名为name
的属性,并将该属性的值指定为1
这一行:
allNames[name] += 1;
简单递增现有属性
我进一步建议,代码示例缺少进一步澄清代码的格式:
var names = ['Alice', 'Bob', 'Tiff', 'Bruce', 'Alice'];
var obj = {};
var countedNames = names.reduce(function(allNames, name) {
if (name in allNames) {
allNames[name]++;
} else {
allNames[name] = 1;
}
return allNames;
}, obj);
console.log(countedNames);
对象文字必须具有要为其赋值的属性。您期望的结果是顶部的javascriptPutvar allNames={}
无效,并将其更改为:names.reduce(function(allNames,name){…
为:names.forEach(function(name){…
,基本相同。主要区别是reduce()
将您从回调返回的值传递回下一次迭代时的回调。我的问题是我不知道对象分支的初始化是如何工作的。感谢您的澄清