js:array.reduce 没有正确累积底层值

  • 本文关键字:array reduce js javascript
  • 更新时间 :
  • 英文 :

arr = [ 
{
day: "monday",
ages: [1,5,2]
},
{
day: "tuesday",
ages: [9]
},
{
day: "monday",
ages: [22,24,28]
},
{
day: "tuesday",
ages: [19]
},
]

我希望结果是一个将每一天作为键并将值作为数组的对象:

预期:

{
monday: [1,5,2,22,24,28],
tuesday: [9,19]
}

我尝试使用reduce,如下所示:

x = arr.reduce((acc,curr) => {
acc[curr.day] = []
acc[curr.day].push(curr.ages)
return acc
})

但它给了我:

{
ages: [1,5,2],
day: "tuesday", 
monday: [22,24,28],
tuesday: [19]
}

为什么要添加agesday作为键?

在reduce{}中缺少初始值,则数组在每次迭代中都不会重用,最后数组不会连接。

arr = [ 
{
day: "monday",
ages: [1,5,2]
},
{
day: "tuesday",
ages: [9]
},
{
day: "monday",
ages: [22,24,28]
},
{
day: "tuesday",
ages: [19]
},
]
console.log(arr.reduce((acc,curr) => {
acc[curr.day] = acc[curr.day] || []
acc[curr.day] = acc[curr.day].concat(curr.ages)
return acc
}, {}));

您可以采用逻辑空赋值??=来分配空数组并推送扩展数组,并将空对象作为累加器的起始值。

x = arr.reduce((acc,curr) => {
acc[curr.day] ??= [];
acc[curr.day].push(...curr.ages);
return acc;
}, {});

当您指定化简器的初始值(即:{})时,它会有所帮助,因此您可以简单地检查该属性是否存在,如果是,则添加到其中,如果没有,则设置它。

const arr = [ 
{
day: "monday",
ages: [1,5,2]
},
{
day: "tuesday",
ages: [9]
},
{
day: "monday",
ages: [22,24,28]
},
{
day: "tuesday",
ages: [19]
},
];
const result = arr.reduce((acc,curr) => {
acc[curr.day] = acc[curr.day] ? [...acc[curr.day], ...curr.ages] : curr.ages; 
return acc;
}, {});
console.log(result);

对于要Array.reduce(Func, InitialValue)的第二个参数,一般规则是,当您需要在修改累加器之前对累加器执行更复杂的操作时,需要它。在下面的示例中,您可以看到一个简单的reduce函数 add ints 不需要初始值。但是第二个示例,我们需要检查acc是否包含curr,然后再将其添加到acc,您需要初始化acc是一个空数组。否则,acc在第一次运行中是未定义的,因此acc.find将引发 null 异常。

const arr = [1, 2, 3, 4];
// Simple summing of ints
console.log(arr.reduce( (acc, curr) => acc += curr) );
// Needing to do something with the accumulator before modiyfing it
const result = arr.reduce( (acc, curr) => {
const found = acc.find(a => a === curr);
if (found) {
// do something
}
return acc;
});

从文档中:

初始值

用作第一次调用的第一个参数的值 回调。如果未提供 initialValue,则 数组将用作初始累加器值并跳过为 当前值。在没有 initialValue 将抛出一个 TypeError。

最新更新