使用 JavaScript 中的 reduce 函数来查找数组中元素出现的次数。

3

我试图找到一个解决方案来查找数组中一个数字出现的次数,并找到了以下解决方案:

const occurrences = [5, 5, 5, 2, 2, 2, 2, 2, 9, 4].reduce(function (acc, curr) {
  return acc[curr] ? ++acc[curr] : acc[curr] = 1, acc
}, {});

console.log(occurrences)

上面的代码按预期工作。但我无法正确理解它是如何工作的。有人能简化并解释一下上面的reduce方法吗?提前致谢。

把它想象成一个 for 循环,在循环外初始化一个对象 obj {}。循环中,检查是否存在 obj[num],如果不存在则初始化为 1,否则将其加 1。 - cmgchess
如果您不理解特定部分,询问会更容易。 - Layhout
到目前为止,每个人都在描述三元运算符(?)的左侧是测试键/值等是否存在,但这是不正确的:它将表达式评估为真值/假值(并且0被包括在假值中)。要检查键是否存在,您需要使用curr in acc ? ... - jsejcksn
2个回答

1
我认为最棘手的部分只是:

return acc[curr] ? ++acc[curr] : acc[curr] = 1, acc

请注意,这只是一个提示:
return (some_expression_with_side_effects), acc

...它返回acc。请查看JavaScript中的逗号运算符以获取详细信息。简而言之,表达式a,b等于b。将其作为reduce的返回值只是确保累加器始终是相同的对象acc。但是,我们在减少过程中向该对象添加属性。

当我们减少数组中的项目时,副作用表达式执行以下操作:

  • 如果当前项目有计数,则将其增加
  • 如果尚未计数,则添加并将其初始化为1。

请注意,我们实际上不使用++acc[curr]的返回值,我们只依赖于它实际上增加存储在acc[curr]处的值的副作用。同样,我们不返回表达式acc[curr] = 1的值,而是依赖于它实际上将acc[curr]设置为初始值1的副作用。


0
JavaScript中的reduce()方法用于遍历数组,并根据某些逻辑从中累积出一个单一的值。
让我们来分解一下代码:
const occurrences = [5, 5, 5, 2, 2, 2, 2, 2, 9, 4].reduce(function (acc, curr) {
    return acc[curr] ? ++acc[curr] : acc[curr] = 1, acc
}, {});

reduce() 方法接受两个参数:

一个在 数组 的每个元素上执行的函数。这个函数接受两个参数:累加器(acc)和当前正在处理的值(curr)。累加器是在每次迭代函数时返回并累加的值。

累加器的可选初始值。在这种情况下,初始值是一个空对象{}

让我们找出作为第一个参数传递给reduce()函数

function (acc, curr) {
  return acc[curr] ? ++acc[curr] : acc[curr] = 1, acc
}

在每次迭代中,此函数会检查当前值(curr)是否已存在于累加器(acc)中作为键。如果是,则递增该键的。如果不是,则将添加到累加器中,并赋予一个值为1的
逻辑分解如下:
return acc[curr] ? ++acc[curr] : acc[curr] = 1, acc
  • acc[curr] ?: 这个语句检查当前的 (curr) 是否存在于累加器 (acc) 中作为一个

  • ++acc[curr]: 如果该键存在,则增加与该相关联的

  • : acc[curr] = 1: 如果该不存在,则将该添加到累加器中,并将其值设置为1。

  • , acc: 最后,返回更新后的累加器。

在每次迭代中,reduce() 方法要么增加现有数字的计数,要么为acc对象中的新数字初始化计数为1。

所有迭代完成后,将累加器对象的最终值分配给变量 occurrences,并打印到控制台:

console.log(occurrences) // {2: 5, 4: 1, 5: 3, 9: 1}

这表明原始数组中数字2出现了5次,数字5出现了3次,数字4出现了1次,数字9出现了1次。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接