从客户端的对象数组中获取最新日期的优雅方法是什么?

Mic*_*ael 41 javascript jquery angularjs

我在项目中使用angularjs.

我从服务器获取了一系列对象.每个对象包含很少的属性,其中一个属性是date属性.

这是我从服务器获得的数组(在json中):

[
  {
    "Address": 25,
    "AlertType": 1,
    "Area": "North",
    "MeasureDate": "2019-02-01T00:01:01.001Z",
    "MeasureValue": -1
  },
  {
    "Address": 26,
    "AlertType": 1,
    "Area": "West",
    "MeasureDate": "2016-04-12T15:13:11.733Z",
    "MeasureValue": -1
  },
  {
    "Address": 25,
    "AlertType": 1,
    "Area": "North",
    "MeasureDate": "2017-02-01T00:01:01.001Z",
    "MeasureValue": -1
  }
          .
          .
          .
]
Run Code Online (Sandbox Code Playgroud)

我需要从阵列中获取最新日期.

从对象数组中获取最新日期的优雅方法是什么?

arc*_*rty 51

一个干净的方法是将每个日期转换为a Date()并取最大值

new Date(Math.max.apply(null, a.map(function(e) {
  return new Date(e.MeasureDate);
})));
Run Code Online (Sandbox Code Playgroud)

a对象数组在哪里.

这样做是将数组中的每个对象映射到使用值创建的日期MeasureDate.然后将此映射的数组应用于Math.max函数以获取最新日期,并将结果转换为日期.

通过将字符串日期映射到JS Date对象,您最终会使用数组中的Min/Max日期等解决方案吗?

-

一个不太干净的解决方案是简单地将对象映射到MeasureDate字符串数组并对其进行排序.这仅适用于您使用的特定日期格式.

a.map(function(e) { return e.MeasureDate; }).sort().reverse()[0]
Run Code Online (Sandbox Code Playgroud)

如果性能是一个问题,您可能希望reduce数组获得最大值而不是使用sortreverse.

  • ES6:新日期(Math.max(... a.map(a => new Date(a.MeasureDate)))); (7认同)
  • 我将如何取回整个对象而不仅仅是日期? (4认同)
  • 对于 Typescript,您必须首先将日期转换为数字 - `new Date(Math.max(...a.map(e => new Date(e.MeasureDate).getTime())));` (4认同)
  • 可能有一种更简单的方法来做到这一点,但我必须编写另一个函数来获取对象:所以你的函数给出了一个日期,假设它被分配给 var `mostRecentDate`。然后我可以这样做来获取对象:`var mostRecentObject = a.filter( e => { var d = new Date( e.MeasureDate ); return d.getTime() == mostRecentDate.getTime();})[ 0];` (2认同)

And*_*ndy 46

继@Travis Heeter 的回答之后,这将返回包含最新日期的对象:

array.reduce((a, b) => (a.MeasureDate > b.MeasureDate ? a : b));

更强大的解决方案可能是Date每次都将字符串转换为对象。如果处理(非常)大型数组,速度可能会明显变慢:

array.reduce((a, b) => {
  return new Date(a.MeasureDate) > new Date(b.MeasureDate) ? a : b;
});
Run Code Online (Sandbox Code Playgroud)

  • 我个人认为单行有点太长,这就是为什么我把它保留为三行,但这是个人喜好 (3认同)
  • 我建议添加一个“initialValue”,以防数组为空。因此,`array.reduce((a, b) => (a.MeasureDate > b.MeasureDate ? a : b), {});`。在本例中是“{}”,它可以是“null”或您想要的任何其他值。 (2认同)

Tra*_*ter 9

如果要获取整个对象,而不仅仅是日期...

如果将OP的对象数组分配给了a它,这就是您如何获取具有最近日期的对象:

var mostRecentDate = new Date(Math.max.apply(null, a.map( e => {
   return new Date(e.MeasureDate);
})));
var mostRecentObject = a.filter( e => { 
    var d = new Date( e.MeasureDate ); 
    return d.getTime() == mostRecentDate.getTime();
})[0];
Run Code Online (Sandbox Code Playgroud)
  1. a.map 从对象数组获取日期。
  2. new Date应用于每个日期,使Date对象成为
  3. Math.max.apply 找到最新的
  4. 我们找到了最新的Date,现在我们需要该对象。
  5. a.filter遍历原始a数组。
  6. 我们需要某种比较日期的方法,因此我们使用.getTime(),它返回自1970年1月1日以来的毫秒数。这将说明时间(如果已定义)以及日期。
  7. 找到正确的日期后,true将返回该日期,并.filter为我们提供该对象。

注意:此解决方案是上述@archyqwerty答案的扩展。他们的解决方案仅提供了对象数组中的最新日期,该解决方案为您提供了该日期所属的整个Object。


小智 5

修改安东·哈拉德(Anton Harald)的答案:我使用的数组使用ModDate而不是MeasureDate。我正在选择最近的日期。这可行。

  getLatestDate(xs) {
   if (xs.length) {
   return xs.reduce((m,v,i) => (v.ModDate > m.ModDate) && i ? v : m).ModDate;
  }
}
Run Code Online (Sandbox Code Playgroud)

m =累加器,v =电流,i =索引

环境:TypeScript,ES6


小智 5

按表现评分的答案:

  1. data.reduce((a, b) => a.MeasureDate > b.MeasureDate ? a : b).MeasureDate
  2. data.map(e => e.MeasureDate).reduce((a, b) => a > b ? a : b)
  3. new Date(Math.max.apply(null, data.map(e => new Date(e.MeasureDate)))).toISOString()

(假设x是数组)