如何从Javascript中的数组中获取每天的最新条目



这个问题听起来可能有点奇怪,但我会解释的
我在Javascript中有一个数组,它来自这样一个api:

[
{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}
]

我想要的是找到每个本地、每天的最新条目
例如:对于给定的数组,我想要一个类似的响应

[
{IdLocal: 12, Date: 04-06-2020T15:25}, // the latest in local 12, day 06
{IdLocal: 12, Date: 04-05-2020T13:40}, // the latest in local 12, day 05
{IdLocal: 13, Date: 04-06-2020T15:25}, // the latest in local 13, day 06
{IdLocal: 13, Date: 04-05-2020T13:40}  // the latest in local 13, day 05
]

正如你所看到的,我希望它每天只返回每个本地人的最新条目。

我认为,如果返回的数组变得巨大,那么反复迭代我的数组可能会非常昂贵
我知道现代Javascript有.map和.filter等非常有用的数组方法,但我是它的创建者。

我在想每个IdLocal和Date的.map,但我真的不确定该怎么做。

首先:这是一种非常奇怪的日期格式。更常见的是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中使用扩频。我们需要对对象的IdLocalDate属性进行特定访问,但如果还有其他属性需要保留,这是一种编写代码的有用方法,而不会到处都是item.Dateitem.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))

这遵循相同的过程,只是修改为重新格式化日期以进行比较。

您的意思是按属性对JSON数组进行排序吗?

var 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"}];

function sortByProperty(property){  
return function(a,b){  
if(a[property] > b[property])  
return 1;  
else if(a[property] < b[property])  
return -1;  
return 0;  
}  
}

items.sort(sortByProperty("Date")); //sort according to date
items.reverse();

console.log(items);

最新更新