谁可以用简单的英语解释下面的累加器 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" Inventory Update"赋值,作为高级算法脚本课程的一部分。
链接:https://www.freecodecamp.org/challenges/inventory-update。 一个是需要更新库存数组(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可以读取" Bowling Ball"例如)与最后一项相同要更新的库存数组,然后更新库存数组中此项目的数量
最后一项在if语句的正上方定义,如下所示:将累积数组的当前长度计算到现在,减去1,并使用该值索引累积的数组。然后将该索引处的元素分配给变量' last'。
另一方面,如果库存为空,则完全添加新项目,即:项目名称和金额。
现在返回新累积的数组。"
如何使用累加器的长度 - 1 来使acc实际累积? (原谅头韵)
我想我最了解这种简化方法是如何构建的,但请在我误读的任何地方纠正我,除了这个特殊的 使用acc.length-1。
干杯,k。
答案 0 :(得分:0)
您是否在询问此部分?
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
答案 1 :(得分:0)
实际的解决方案包括连接和排序两个数组,然后才减少它们。 在这种情况下,每当我们评估一个新项目时,如果它的名称不等于最后一个累加项目,则表示它是一个新项目。
使用您的示例,我们减少的列表是:
[
[ 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']
,当我们比较字符串时,我们会进入第一个条件。
答案 2 :(得分:0)
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
,可能需要一些时间才能完全理解它。它的使用几乎总是可以减少容易出错的应用程序,因此我主张花一些时间来充分了解它的功能以及何时使用它。