如何对reduce对象中的特定元素求和?

How to sum specific element in reduce object?

假设我有这个对象数组:

const arrayOfObjects = [
  { task: "work", time: 1 }, 
  { task: "travel", time: 4 }, 
  { task: "work", time: 5 }, 
  { task: "eat", time: 3 }, 
  { task: "eat", time: 1 }, 
  { task: "eat", time: 5 }
];

并且我想要 return 单个对象,return 将每个键作为任务,将每个值作为键的所有值的总和。 例如,上面数组的生成对象应该是:

sumOfObejcts = {
  work: 6,
  travel: 4,
  eat: 9
}

如何正确使用 reduce 函数? 我不知道如何对特定键的所有项目求和,这是我从示例中尝试几次后所做的:

    const sumOfObejcts = arrayOfObjects.reduce((acc, items) => {
      let { task, time } = items;
      return { ...acc, [task]: [...(acc[task] || []), time] };
    }, {});

我得到的输出是:

{
  work: [1, 5],
  travel: [4],
  eat: [3, 1, 5]
}

所以,我只想return值出现的总和。

您的解决方案非常接近;除了您在每次迭代中创建值数组,而不是对当前时间值求和。

在这里,我使用三元语句更改了您分配给键的值。这将检查任务是否存在于累加器对象中;如果任务已经存在,这意味着这个任务已经有一个总和,因此我们只需要将当前时间添加到现有总和上。否则,如果累加器对象没有任务,则该值将使用当前任务的时间填充。

const sumOfObjects = arrayOfObjects
  .reduce((acc, item) =>
    ({ ...acc, [item.task]: (
       acc[item.task] // does the task exist in the accumulator object?
       ? acc[item.task] + item.time // if so, set a value equal to the current task's time plus the existing value
       : item.time // otherwise, prime the task's value to the current time
      ) })
  , {});

使用forEach并构建对象

const sumOfObjects = (arr, all = {}) => (
  arr.forEach(({ task, time }) => (all[task] = (all[task] ?? 0) + time)), all
);

const arrayOfObjects = [
  { task: "work", time: 1 },
  { task: "travel", time: 4 },
  { task: "work", time: 5 },
  { task: "eat", time: 3 },
  { task: "eat", time: 1 },
  { task: "eat", time: 5 },
];

console.log(sumOfObjects(arrayOfObjects));