我有一个不同的对象数组。有些具有相同的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()
来获取包含所有匹配项的对象呢?
如果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 }), {});
Jack Bashford的答案似乎是你要找的。我只想补充一点,这是一个非常常见的操作,通常称为groupBy
.这在大多数功能帮助程序库(例如 Lodash(中实现。您也可以使用以下方法自行实现它:
const groupBy = (cb, arr) =>
arr.reduce((grouped, el) => {
const key = cb(el)
return {
...grouped,
[key]: [...grouped[key] || [], el]
}
}, {})
(请注意,上面的实现只是一个示例,不应被视为高性能实现。请参阅 Lodash 组通过实现。
然后对于您的用例:
groupBy(el => el.date, arr)
如果您打算执行类似的操作,这将很有帮助。