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]
}
为什么要添加ages
和day
作为键?
在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。