Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何减少这里的工作量?_Javascript_Reduce - Fatal编程技术网

Javascript 如何减少这里的工作量?

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;

我正在阅读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;
    }

    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);

对象文字必须具有要为其赋值的属性。您期望的结果是顶部的javascriptPut
var allNames={}
无效,并将其更改为:
names.reduce(function(allNames,name){…
为:
names.forEach(function(name){…
,基本相同。主要区别是
reduce()
将您从回调返回的值传递回下一次迭代时的回调。我的问题是我不知道对象分支的初始化是如何工作的。感谢您的澄清