我在Javascript中有一个非常具体的问题。我有一个对象数组,每个对象包含一个日期。
const array = [
{name: 'first', date: '2020-05-06'},
{name: 'second', date: '2020-04-07'},
{name: 'third', date: '2020-05-06'},
{name: 'fourth', date: '2020-04-07'},
{name: 'fifth', date: '2020-04-09'}
]
对于数组中的每个唯一日期,我需要创建一个对象,key为该唯一日期并将数组中的所有元素放入该对象中:
[{name: 'first', date: '2020-05-06'}, {name: 'third', date: '2020-05-06'}]
[{name: 'second', date: '2020-04-07'} {name: 'fourth', date: '2020-04-07'}]
[{name: 'fifth', date: '2020-04-09'}]
任何帮助都意义重大。谢谢大家!
几乎任何涉及分组的数组特定任务都将通过基于reduce
的方法最方便地解决。
不管OP的最终数据结构是什么,我们将从一个对象的聚合开始,该对象将具有date
特定条目的特征,其中每个键代表一个唯一的日期值,每个值是具有相同日期的项的数组。
为了得到这样一个分组数组的数组,可以将简化后的对象传递给Object.values
。
原因之一总是可以通过首先应用sort
任务来强制日期特定项的优先级。
function groupAndCollectSameDateItem(result, item) {
// access item date.
const { date } = item;
// access or create `date` specific
// group array and collect item.
(result[date] ??= []).push(item);
return result;
}
const dateItems = [
{ name: 'first', date: '2020-05-06' },
{ name: 'second', date: '2020-04-07' },
{ name: 'third', date: '2020-05-06' },
{ name: 'fourth', date: '2020-04-07' },
{ name: 'fifth', date: '2020-04-09' },
];
console.log(
'index/map of arrays of same date items grouped by a date key ...',
dateItems
.reduce(groupAndCollectSameDateItem, {})
);
console.log(
'sort items in ascending date order before creating the index ...',
dateItems
.sort((a, b) =>
new Date(a.date).getTime() - new Date(b.date).getTime()
)
.reduce(groupAndCollectSameDateItem, {})
);
console.log(
'array of arrays of same date items in ascending date order ...',
Object
.values(
dateItems
.sort((a, b) =>
new Date(a.date).getTime() - new Date(b.date).getTime()
)
.reduce(groupAndCollectSameDateItem, {})
)
);
.as-console-wrapper { min-height: 100%!important; top: 0; }
编辑
"…我们的项目eslint不允许?? ?=符号。- - - - - -Marin"
不使用逻辑空赋值操作符的替代实现可能类似于下一个示例代码…
function groupAndCollectSameDateItem(result, item) {
// access item date.
const { date } = item;
// access or create `date` specific
// group array and collect item.
let groupList = result[date];
if (!groupList) {
groupList = result[date] = [];
}
groupList.push(item)
return result;
}
const dateItems = [
{ name: 'first', date: '2020-05-06' },
{ name: 'second', date: '2020-04-07' },
{ name: 'third', date: '2020-05-06' },
{ name: 'fourth', date: '2020-04-07' },
{ name: 'fifth', date: '2020-04-09' },
];
console.log(
'index/map of arrays of same date items grouped by a date key ...',
dateItems
.reduce(groupAndCollectSameDateItem, {})
);
.as-console-wrapper { min-height: 100%!important; top: 0; }
你可以使用。reduce(),我留给你这个例子:
let foo = [
{name: 'first', date: '2020-05-06'},
{name: 'second', date: '2020-04-07'},
{name: 'third', date: '2020-05-06'},
{name: 'fourth', date: '2020-04-07'},
{name: 'fifth', date: '2020-04-09'}
];
let boo = foo.reduce((acc, elem) => {
(acc[elem.date] ??= []).push(elem);
// since OP said they have eslint issues with ??=
// following may be used instead of the above line
// acc[elem.date] = (acc[elem.date] || []).concat([elem])
return acc;
}, {});
console.log('output: ', boo);
结果:
{
'2020-05-06': [
{ name: 'first', date: '2020-05-06' },
{ name: 'third', date: '2020-05-06' }
],
'2020-04-07': [
{ name: 'second', date: '2020-04-07' },
{ name: 'fourth', date: '2020-04-07' }
],
'2020-04-09': [ { name: 'fifth', date: '2020-04-09' } ]
}
您需要的是groupBy实现。Lodash库有https://lodash.com/docs/#groupBy
示例:https://stackblitz.com/edit/js-twywom?file=index.js