首页 > 解决方案 > JavaScript - 在多个相同长度的对象数组中组合和添加值

问题描述

我希望通过匹配相同的日期字符串来减少对象数组,并将这些匹配日期的总数加在一起并将它们组合成一个对象。我可以有几千个项目长的数组,所以我试图增加(尽可能)和复杂性。

// 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
    }
]

我编写了一个脚本来检查以确保datetotal属性中的所有值都以它们需要的方式存在,但我最终还是得到了一个错误的数组。这里的假设是我的 reduce 函数不正确。

标签: javascriptarrays

解决方案


您的代码几乎是正确的。问题是您将 Map 键设置为日期,但尝试get通过传递带有日期的数组而不是单独的日期来传递项目。

您正在使用:acc.get([obj.date]),当您可能想要:(acc.get(obj.date)没有[ ]

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},]

let s = objArr.reduce((acc, obj) => {
    // not acc.get([obj.date]) !
    acc.set(obj.date, (acc.get(obj.date) || 0) + obj.total);
    return acc;
  }, new Map())

// turn the Map into something that will display:
console.log([...s.entries()].map(([date, total]) => ({date, total})))


推荐阅读