JavaScript-在多个相同长度的对象数组中组合和添加值
我希望通过匹配相同的日期字符串来减少对象数组,并将这些匹配日期的总数相加,然后将它们组合成一个对象。我可以有几千个项目长的数组,所以我试图增加(在可能的情况下)和复杂性JavaScript-在多个相同长度的对象数组中组合和添加值,javascript,arrays,Javascript,Arrays,我希望通过匹配相同的日期字符串来减少对象数组,并将这些匹配日期的总数相加,然后将它们组合成一个对象。我可以有几千个项目长的数组,所以我试图增加(在可能的情况下)和复杂性 // before let objArr = [ { date: '01/01/2018', total: 1 }, { date: '01/01/2018', total: 2 }, { date: '01/
// before
let objArr = [
{
date: '01/01/2018',
total: 1
},
{
date: '01/01/2018',
total: 2
},
{
date: '01/02/2018',
total: 3
},
{
date: '01/02/2018',
total: 4
},
...
]
// final result
let finalArr = [
{
date: '01/01/2018',
total: 3
},
{
date: '01/02/2018',
total: 7
},
...
]
我似乎无法掌握使用reduce减少它们的诀窍:
objArr.reduce((acc, obj) => {
acc.set(obj.date, (acc.get([obj.date]) || 0) + obj.total);
return acc;
}, new Map())
结果总是以错误的总数结束,或者最后几个数组对象如下所示:
// bad output
badArray = [
...,
{
date: '01/02/2018',
total: 4
},
{
date: undefined,
total: NaN
},
{
date: undefined,
total: NaN
}
]
我编写了一个脚本进行检查,以确保
date
和total
属性中的所有值都以它们所需的方式存在,但最终还是得到了一个错误的数组。这里的假设是我的reduce函数不正确。您的代码几乎正确。问题是,您正在将映射键设置为日期,但试图通过传递带有日期的数组而不是仅传递日期来获取项目
您正在使用:acc.get([obj.date])
,而您可能需要:acc.get(obj.date)
(不带[]
)
let objArr=[{date:'01/01/2018',总计:1},{date:'01/01/2018',总计:2},{date:'01/02/2018',总计:3},{date:'01/02/2018',总计:4},]
设s=objArr.reduce((acc,obj)=>{
//非附件获取([目标日期])!
acc.set(obj.date)(acc.get(obj.date)| | 0)+obj.total);
返回acc;
},新映射())
//将地图转换为可显示以下内容的内容:
console.log([…s.entries()].map([date,total])=>({date,total}))
我认为Mark Meyer的答案很好,但这也是另一个使用空数组作为初始值而不是映射的选项(始终保持输入的原始结构):
let objArr=[{date:'01/01/2018',总计:1},{date:'01/01/2018',总计:2},{date:'01/02/2018',总计:3},{date:'01/02/2018',总计:4},];
常量结果=对象减少((acc,obj)=>{
const existingObj=acc.find((o)=>o.date==obj.date);
如果(现有对象){
现有obj.total+=obj.total;
}否则{
加速推力(obj);
}
返回acc;
}, []);
控制台日志(结果)代码>如果您希望输出为数组,为什么要使用映射?感谢您提供了第一个映射。这似乎奏效了。但我在映射时遇到“s.entries(…).slice不是函数”错误。我来看看问题是什么。@razorsyntax条目不是数组,它是一个映射迭代器,除非先使用类似于array.from(s)
或[…s]
的方法将其转换为数组,否则无法对其进行切片。