首页 > 解决方案 > 如何使用reduce返回一个以数组为值的映射对象?

问题描述

我有一系列不同的对象。有些具有相同的date价值。我想将相同date的对象组合在一起并返回一个映射对象,其中每个对象date都是键,其值是具有相同日期的对象数组。这是数组:

const arr = [
  {
    date: '2/2/20',
    name: 'joe',
    age: 22
  },
  {
    date: '3/3/20',
    name: 'john',
    age: 67
  },
  {
    date: '2/2/20',
    name: 'chuck',
    age: 34
  },
  {
    date: '3/3/20',
    name: 'bob',
    age: 28
  },
  {
    date: '4/4/20',
    name: 'bill',
    age: 51
  }
]

我知道这样的事情可以用 来完成map().filter(),但这不是我想要的,而且我正在尝试这样做reduce()以节省资源。

到目前为止,我有:

arr.reduce((acc, person) => {
  acc[person.date] = [ person ];
  return acc;
}, {});

这仅返回最后一个匹配项,而不是所有匹配项:

{
  '2/2/20': [ { date: '2/2/20', name: 'chuck', age: 34 } ],
  '3/3/20': [ { date: '3/3/20', name: 'bob', age: 28 } ],
  '4/4/20': [ { date: '4/4/20', name: 'bill', age: 51 } ]
}

我已经尝试过这个解决方案的其他方面,但我似乎无法做到正确。我也知道如何获取返回匹配数的映射对象,但这仍然不是我的解决方案:

arr.reduce((acc, person) => {
  acc[person.date] = acc[person.date] + 1 || 1
  return acc
}, {})

这将返回:

{ '2/2/20': 2, '3/3/20': 2, '4/4/20': 1 }

那么如何使用reduce()来获取包含所有匹配项的对象呢?

标签: javascriptarraysobject

解决方案


acc[person.date]如果不存在,则初始化为空数组,并且push不管:

arr.reduce((acc, person) => {
    acc[person.date] = (acc[person.date] || []);
    acc[person.date].push(person);
    return acc;
}, {});

解构单线/传播方式:

arr.reduce((acc, { date, ...o }) => ({ ...acc, [date]: [...(acc[date] || []), { date, ...o }), {});

推荐阅读