【问题标题】:Javascript reduce accumulator explainedJavascript减少累加器解释
【发布时间】:2018-01-23 13:07:56
【问题描述】:

谁能用简单的英语解释一下下面的累加器acc结构?

return arr1.reduce(function(acc, curr){  
      var last = acc[acc.length-1];  
        if(acc.length > 0 && curr[1]===last[1]) {
        last[0] += curr[0];
      } else acc.push(curr);
      return acc;
      }, []);
    }

这个reduce 方法可用于解决 FreeCodeCamp 的“库存更新”任务,作为高级算法脚本课程的一部分。

需要使用“新交付”数组中的新商品更新库存数组 (arr1) 中的现有商品。

两个测试数组,一个当前库存curInv和一个新交付newInv,可能如下:

var curInv = [
    [21, "Bowling Ball"],
    [2, "Dirty Sock"],
    [1, "Hair Pin"],
    [5, "Microphone"]
];

var newInv = [
    [2, "Hair Pin"],
    [3, "Half-Eaten Apple"],
    [67, "Bowling Ball"],
    [7, "Toothpaste"]
];

在找到几篇关于 Javascript reduce 方法的优秀文章(如 this post 和 egghead.io 上的一个很棒的视频课程)后,并以某种方式感知到它正在骚扰的力量,我会阅读以下方法:

减少库存数组,首先创建一个空数组 [ ](初始值),然后应用以下回调函数:

如果库存数组当前不为空(长度大于零),并且当前处理的项目的名称(例如 curr 的索引 0 可以读为“保龄球”)与库存的最后一项相同数组被更新,然后更新库存数组中这个项目的数量。

最后一项定义在 if 语句的正上方,如下:将累加数组的当前长度减去 1,然后使用该值对累加数组进行索引。然后将该索引处的元素分配给变量“last”。

另一方面,如果库存是空的,则完全添加新项目,即:项目名称和数量。 现在返回新累积的数组。"*

如何使用累加器的length - 1 来使 acc 实际累加? (请原谅头韵)

我想我大部分了解这个 reduce 方法是如何构建的,但是请在我误读的地方纠正我),除了这个特别的 使用acc.length-1

干杯,k。

【问题讨论】:

  • 这个reducer是如何解决这个问题的?你能分享一下实际通话吗?
  • @thedude:一种解决方案似乎是将reduce方法与concat结合起来,并按字母顺序排序Repl.it link

标签: javascript for-loop reduce accumulator


【解决方案1】:

您是在问这个部分吗?

var last = acc[acc.length-1]; 

如果是这样 acc.length-1 是因为在数组中

acc = [a,b,c,d]
acc.length is equal to 4

要访问元素 d,您将通过

访问它
acc[3];  //which equals d

那是因为我们从 0,1,2,3 开始计算位置

【讨论】:

    【解决方案2】:

    实际的解决方案是对两个数组进行连接和排序,然后再减少它们。 在这种情况下,每当我们评估一个新项目时,如果它的名称不等于最后一个累加器项目,则意味着它是一个新项目。

    使用您的示例,我们要减少的列表是:

    [
      [ 21, 'Bowling Ball' ],
      [ 67, 'Bowling Ball' ],
      [ 2, 'Dirty Sock' ],
      [ 1, 'Hair Pin' ],
      [ 2, 'Hair Pin' ],
      [ 3, 'Half-Eaten Apple' ],
      [ 5, 'Microphone' ],
      [ 7, 'Toothpaste' ]
    ]
    

    所以当我们遇到第二项时,累加器中的最后一个值是[21, 'Boweling Ball'],当我们比较字符串时,我们进入第一个条件。

    【讨论】:

    • 对!谢谢,看到减少列表使它点击; 'Bowling Ball' as 'last' item 表示当下一个'Bowling Ball'出现时,函数加1
    【解决方案3】:

    tl;dr:看看这个REPL example


    Reduce 能够将原始数组减少为函数中定义的值。

    例如,如果我们有一个整数数组想要计算它的总和,我们可以使用reduce 来实现。

    当然,您可能会问为什么要使用reduce 而不是for loop

    reduce 是更好选择的主要原因是因为我们作为参数传递的 reducer 函数是pure。这意味着,计算结果不需要“额外”或“外部”变量。在for 循环中,我们需要有一个totalSum 变量来计算结果,而在reduce 版本中则不需要。

    回到 OP 的示例,这就是我们如何构造 reduce 以按相同名称的邀请进行分组:

    // reduce example
    const reducer = (accumulator, currentValue) => {
        if (accumulator.length === 0) {
            accumulator.push(currentValue);
            return accumulator;
        }
    
        const index = accumulator.findIndex(el => el[1] === currentValue[1]);
    
        if (index !== -1) {
            accumulator[index][0] += currentValue[0];
            return accumulator;
        }
        accumulator.push(currentValue);
        return accumulator
    };
    

    这是带有 for 循环的等效版本:

    // for loop example
    let withForLoop = (input) => {
        let res = [];
        for (let i = 0; i < input.length; i++) {
            let currInput = input[i];
            const index = res.findIndex(el => el[1] === currInput[1]);
            if (index !== -1) {
                res[index][0] += currInput[0];
                continue;
            }
            res.push(currInput);
        }
        return res;
    }
    

    如果您是reduce 的新手,您可能需要一些时间才能完全理解它。它的使用几乎总是导致应用程序不太容易出错,因此我建议花一些时间来充分了解它的功能以及何时使用它。

    【讨论】:

      猜你喜欢
      • 2015-06-04
      • 2012-11-16
      • 2022-01-08
      • 2014-12-16
      • 2018-08-05
      • 2015-05-18
      • 2018-10-18
      • 2018-07-29
      • 2020-08-11
      相关资源
      最近更新 更多