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

标签 javascript arrays node.js date ecmascript-6

这个问题可能听起来有点奇怪,但我会解释一下。
我有一个 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))

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

关于javascript - 如何从 Javascript 数组中获取每天的最新条目?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61066925/

相关文章:

javascript - 尝试比较 Javascript 中不同数组中的对象

mysql - Sequelize 具有相同外键的多对多表只选择一个值

node.js - 如何在 Nodejs 中使用 Observable Plot?

javascript - 如何在新窗口中打开视频

javascript - 我如何将全局模板助手放在 Meteor 中?

c - 如何用随机数填充数组以使它们不同?

c# - 在c#中将字符串中的值读入数组

javascript - CommonJS 单例模块中的循环依赖

javascript - Angular Directive(指令)监视变量未触发

javascript - JQuery 幻灯片 : fade effect