[英]How to group objects in an array and sort them depending on an object property
[英]How to group and sort object array?
我有一个对象数组,我必须对其进行分组和排序:
[
{
id: 123,
group: 'abc',
metadata: {
name: 'tom'
},
date: ISODate("2019-07-08T20:33:40.475Z")
},
{
id: 456,
group: 'def',
metadata: {
name: 'bob'
},
date: ISODate("2019-07-08T20:33:40.475Z")
},
{
id: 789,
group: 'def',
metadata: {
name: 'bob'
},
date: ISODate("2019-07-10T20:33:40.475Z")
},
{
id: 234,
group: 'ghi',
metadata: {
name: 'frank'
},
date: ISODate("2019-07-10T20:33:40.475Z")
},
{
id: 567,
group: 'abc',
metadata: {
name: 'tom'
},
date: ISODate("2019-07-10T20:33:40.475Z")
}
]
首先,我需要按组值对元素进行分组,然后按日期对此分组数组中的元素进行排序。
对于分组,我尝试了以下方法:
const result = array.reduce(function (r, a) {
r[a.group] = r[a.group] || [];
r[a.group].push(a);
return r;
}, Object.create(null));
但是结果不符合预期,并且没有按日期对元素进行排序。
结果可能/应该看起来像这样:
[
[
{
id: 123,
group: 'abc',
metadata: {
name: 'tom'
},
date: ISODate("2019-07-08T20:33:40.475Z")
},
{
id: 567,
group: 'abc',
metadata: {
name: 'tom'
},
date: ISODate("2019-07-10T20:33:40.475Z")
}
],
[
{
id: 456,
group: 'def',
metadata: {
name: 'bob'
},
date: ISODate("2019-07-08T20:33:40.475Z")
},
{
id: 789,
group: 'def',
metadata: {
name: 'bob'
},
date: ISODate("2019-07-10T20:33:40.475Z")
}
],
[
{
id: 234,
group: 'ghi',
metadata: {
name: 'frank'
},
date: ISODate("2019-07-10T20:33:40.475Z")
}
]
]
使用reduce
到组中的值,并sort
对它们进行排序,使用map
以及由于嵌套阵列结构。
const arr = [{id:123,group:'abc',metadata:{name:'tom'},date:"2019-07-08T20:33:40.475Z"},{id:456,group:'def',metadata:{name:'bob'},date:"2019-07-08T20:33:40.475Z"},{id:789,group:'def',metadata:{name:'bob'},date:"2019-07-10T20:33:40.475Z"},{id:234,group:'ghi',metadata:{name:'frank'},date:"2019-07-10T20:33:40.475Z"},{id:567,group:'abc',metadata:{name:'tom'},date:"2019-07-10T20:33:40.475Z"}]; const res = Object.values(arr.reduce((a, { group, ...r }) => { (a[group] = a[group] || []).push({ group, ...r }); return a; }, {})).map(e => e.sort(({ date: a }, { date: b }) => new Date(a) - new Date(b))); console.log(res);
.as-console-wrapper { max-height: 100% !important; top: auto; }
(我已取出ISODate
函数,只是保留了字符串日期以使代码段可执行。)
我建议使用lodash 。
var ISODate = function(str) { return str };
var data = [
{
id: 123,
group: 'abc',
metadata: {
name: 'tom'
},
date: ISODate("2019-07-08T20:33:40.475Z")
},
{
id: 456,
group: 'def',
metadata: {
name: 'bob'
},
date: ISODate("2019-07-08T20:33:40.475Z")
},
{
id: 789,
group: 'def',
metadata: {
name: 'bob'
},
date: ISODate("2019-07-10T20:33:40.475Z")
},
{
id: 234,
group: 'ghi',
metadata: {
name: 'frank'
},
date: ISODate("2019-07-10T20:33:40.475Z")
},
{
id: 567,
group: 'abc',
metadata: {
name: 'tom'
},
date: ISODate("2019-07-10T20:33:40.475Z")
}
]
console.log(
_.mapValues(
_.groupBy(data, 'group'),
function(item) { return _.orderBy(item, ['date'], ['asc']) }
)
)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.