第一件事:这是一种非常奇怪的日期格式。更常见的是ISO 8601,它会使用这个:
{IdLocal: 12, Date: "2020-04-06T15:25"},
而不是这个:
{IdLocal: 12, Date: "04-06-2020T15:25"},
标准格式可让您以自然的方式对日期进行排序和比较,并且与其他系统的互操作性更强。所以,如果你可以切换到这种日期格式,代码还不错:
const extract = items => Object .values (items .reduce (
(a, {IdLocal, Date, ...rest}) => {
const key = IdLocal + ':' + Date.slice(0, 10);
if (! (key in a) || Date > a [key] .Date) {
a[key] = {IdLocal, Date, ...rest}
}
return a
},
{}
))
const items = [{IdLocal: 12, Date: '2020-04-06T15:25'}, {IdLocal: 12, Date: '2020-04-06T10:37'}, {IdLocal: 12, Date: '2020-04-05T12:30'}, {IdLocal: 12, Date: '2020-04-05T13:40'}, {IdLocal: 13, Date: '2020-04-06T15:25'}, {IdLocal: 13, Date: '2020-04-06T10:37'}, {IdLocal: 13, Date: '2020-04-05T12:30'}, {IdLocal: 13, Date: '2020-04-05T13:40'}]
console .log (extract (items))
.as-console-wrapper {min-height: 100% !important; top: 0}
我们使用由IdLocal 变量和时间戳的日期部分组成的键对列表进行直接缩减。它会生成如下内容:
{
"12:2020-04-05": {IdLocal: 12, Date: "2020-04-05T13:40"},
"12:2020-04-06": {IdLocal: 12, Date: "2020-04-06T15:25"},
"13:2020-04-05": {IdLocal: 13, Date: "2020-04-05T13:40"},
"13:2020-04-06": {IdLocal: 13, Date: "2020-04-06T15:25"}
}
然后,通过在这个结果上调用Object.values,我们得到
[
{IdLocal: 12, Date: "2020-04-05T13:40"},
{IdLocal: 12, Date: "2020-04-06T15:25"},
{IdLocal: 13, Date: "2020-04-05T13:40"},
{IdLocal: 13, Date: "2020-04-06T15:25"}
]
请注意此处在...rest 中使用传播。我们需要对对象的 IdLocal 和 Date 属性进行特定访问,但是如果您需要保留其他属性,这是编写代码的有用方法,而不会到处乱扔item.Date 和 item.IdLocal .
我个人会写这个有点不同,因为我更喜欢使用表达式而不是语句,并且我更喜欢不改变数据,即使是 reduce 调用的累加器,除非性能测试表明不改变是一个瓶颈。所以我可能会这样写:
const extract = items => Object .values (items .reduce (
(a, {IdLocal, Date, ...rest}, _, __, key = IdLocal + ':' + Date.slice(0, 10)) => ({
... a,
[key]: (!a [key] || Date > a[key].Date) ? ({IdLocal, Date, ...rest}) : a [key]
}),
{}
))
但这两个版本的想法都是一样的。
如果您坚持使用这种日期格式,那也不是难事。我只是介绍一个会格式化日期的函数,然后在几个地方使用它:
const formatDate = (d) => `${d.slice(6, 10)}-${d.slice(0, 5)}${d.slice(10)}`
const extract = items => Object .values (items .reduce (
(a, {IdLocal, Date, ...rest}) => {
const dateStr = formatDate(Date)
const key = IdLocal + ':' + dateStr.slice(0, 10)
if (! (key in a) || dateStr > formatDate (a[key] .Date)) {
a [key] = {IdLocal, Date, ...rest}
}
return a
},
{}
))
const items = [{IdLocal: 12, Date: '04-06-2020T15:25'}, {IdLocal: 12, Date: '04-06-2020T10:37'}, {IdLocal: 12, Date: '04-05-2020T12:30'}, {IdLocal: 12, Date: '04-05-2020T13:40'}, {IdLocal: 13, Date: '04-06-2020T15:25'}, {IdLocal: 13, Date: '04-06-2020T10:37'}, {IdLocal: 13, Date: '04-05-2020T12:30'}, {IdLocal: 13, Date: '04-05-2020T13:40'}]
console .log (extract (items))
这遵循相同的过程,只是修改为重新格式化日期以进行比较。