如何减少这里的工作?

How does reduce work here?

我正在阅读 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 将采用 array 并将其缩减为单个值。在您的情况下,您正在 reducearray 个名称分解为包含名称和该名称在 array 中存在的次数的哈希值。 reduce 的最后一个参数是初始起始值。在这种情况下,你给它一个空的 object。此 object 在您的回调函数中由 allNames 表示。因此,对于 array 中的每个 name,如果该 name 已经存在,您将签入 allNames。如果是,则增加 name 的计数,否则将其设置为 1.

reduce 函数以起始值开始,后续 "reductions" 传入数据将对其进行修改。在这种情况下,起始值是 {},即对象文字,从代码的倒数第二行开始。在这种情况下,将应用所有新修改的逐渐累积的值称为 allNames。当 reduce 函数对 allNames[name] 做某事时,它正在对键为 nameallNames 对象的 属性 做某事,例如'Alice'。因此,例如,第一次遇到 Alice 的名字时,将创建键为 Alice 的 属性 并为其分配值 1。这将继续通过原始输入,最终产生您指定的最终结果。

Array.prototype.reduce() 是一个累加器函数 - 它将遍历数组中的所有元素并对它们执行一些操作以将它们减少为单个值。在此示例中,我们将单个值初始化为一个空对象 allnames = {}。当我们遍历名称时,我们检查该名称是否已作为键存在于对象中 - 如果存在,则我们增加计数,如果不存在,则我们将该键值对初始化为 <name>: 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 上的文档以减少: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce

你可以看到它接受一个回调函数和一个初始值。在这种情况下,您将传递一个空对象 {} 作为初始值(请参阅倒数第二行)

reduce方法然后"applies a function against an accumulator and each value of the array (from left-to-right) to reduce it to a single value."

这个单一值从空对象开始,然后根据回调函数体内的条件逻辑在此对象中添加和递增属性。

您的线路:

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