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

Posted

技术标签:

【中文标题】从客户端的对象数组中获取最新日期的优雅方法是啥?【英文标题】:What is the elegant way to get the latest date from array of objects in client side?从客户端的对象数组中获取最新日期的优雅方法是什么? 【发布时间】:2016-08-03 07:09:13 【问题描述】:

我在项目中使用 angularjs。

我从服务器获取对象数组。 每个对象都包含几个属性,其中一个是日期属性。

这是我从服务器获取的数组(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
  
          .
          .
          .
]

我需要从数组中获取最新日期。

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

【问题讨论】:

循环查找最新日期。 @epascarello,我是否必须将其转换为 Date javascript 对象。 是的,您需要将字符串转换为日期。 你不需要转换它。可以按原样订购。而且,事实上,有一些论点认为引入转换为引入更多潜在领域出现问题(解析等)打开了底线。 由于您选择的特定格式,您不必转换它。我认为最好进行转换,因为如果您的应用程序曾经使用不同的格式或接受多种格式,那么这可能会中断,而将其解析为日期然后排序可确保它确实是最新日期(可能不一定是最后一个有序的字符串)。例如,如果您开始接受 MM/DD/YYYY 日期,则字符串顺序可能与日期顺序大不相同。 【参考方案1】:

一种简洁的方法是将每个日期转换为 Date() 并取最大值

ES6:

new Date(Math.max(...a.map(e => new Date(e.MeasureDate))));

JS:

new Date(Math.max.apply(null, a.map(function(e) 
  return new Date(e.MeasureDate);
)));

其中a 是对象数组。

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

通过将字符串日期映射到 JS Date 对象,您最终会使用像 Min/Max of dates in an array? 这样的解决方案

--

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

a.map(function(e)  return e.MeasureDate; ).sort().reverse()[0]

如果关注性能,您可能希望reduce 数组获得最大值,而不是使用sortreverse

【讨论】:

有趣,辛辣的解决方案。不知道您可以立即将日期对象应用于 Math.max。 ES6: new Date(Math.max(...a.map(a=> new Date(a.MeasureDate)))); 如何获取整个对象,而不仅仅是日期? 可能有更简单的方法可以做到这一点,但我必须编写另一个函数来获取对象:所以你的函数给出了一个日期,假设它分配给了 var mostRecentDate。然后我可以这样做来获取对象:var mostRecentObject = a.filter( e => var d = new Date( e.MeasureDate ); return d.getTime() == mostRecentDate.getTime();)[0]; 你是个传奇【参考方案2】:

除了@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;
);

【讨论】:

这是一个衬里:array.reduce((a, b) => new Date(a.MeasureDate) > new Date(b.MeasureDate) ? a : b) 个人觉得单行有点长,所以我把它保留为三行,但这是个人喜好【参考方案3】:

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

如果将 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];
    a.map 从对象数组中获取日期。 new Date 应用于每个日期,使 Date 对象 Math.max.apply 查找最新的 我们找到了最近的日期,现在我们需要该对象。 a.filter 循环遍历原始的 a 数组。 我们需要一些方法来比较日期,所以我们使用.getTime(),它返回自 1970 年 1 月 1 日以来的毫秒数。这将考虑时间(如果已定义)以及日期。 找到正确的日期后,true 被返回,.filter 只为我们提供该对象。

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

【讨论】:

【参考方案4】:

修改 Anton Harald 的回答:我使用的数组使用 ModDate 而不是 MeasureDate。我正在选择最近的日期。这行得通。

  getLatestDate(xs) 
   if (xs.length) 
   return xs.reduce((m,v,i) => (v.ModDate > m.ModDate) && i ? v : m).ModDate;
  

m = 累加器,v = 当前,i = 索引

环境:TypeScript、ES6

【讨论】:

这很有用,尽管xs 需要是一个数组才能工作。在我的特殊情况下,我有一个以对象为值的字典,因此我可以将它与 Object.values(myDict).reduce(...) 一起使用 @Felipe 请注意,这不能仅用于 ES7 ***.com/questions/52304422/…【参考方案5】:
function getLatestDate(data) 
   // convert to timestamp and sort
   var sorted_ms = data.map(function(item) 
      return new Date(item.MeasureDate).getTime()
   ).sort(); 
   // take latest
   var latest_ms = sorted_ms[sorted_ms.length-1];
   // convert to js date object 
   return new Date(latest_ms);


var data = [MeasureDate: "2014-10-04T16:10:00",
            MeasureDate: "2013-10-04T16:10:00",
            MeasureDate: "2012-10-04T16:10:00"];

getLatestDate(data).toString(); // "Sat Oct 04 2014 18:10:00 GMT+0200 (CEST)"

此函数将最新日期作为 JavaScript 日期对象返回。您还可以使用 Date-Object 方法 toISOString() 将其转换为 ISO-String(源数据的格式)。

var date_str = "2012-10-04T16:10:00";
(new Date(date_str)).toISOString(); // "2012-10-04T16:10:00.000Z"

如您所见,该方法的结果最后总是包含零毫秒。如果您因此需要原始 ISO 数据字符串,您可能需要使用以下函数:

function getLatestDate2(data) 

   var sorted = data.map(function(item) 
      var MeasureDate = item.MeasureDate;
      return original_str: MeasureDate,
              in_ms: (new Date(MeasureDate)).getTime()
   ).sort(function(item1, item2) 
      return (item1.in_ms < item2.in_ms)
   ); 

   // take latest
   var latest = sorted[0];

   return latest.original_str;


getLatestDate2(data); // "2014-10-04T16:10:00"

【讨论】:

【参考方案6】:

还进一步到@TravisHeeter 的回答..

您可以使用 .find() 方法代替使用 'filter' 并抓取 [0] 的数组索引,如下所示:

....

const mostRecentObject = a.find( e =>  
    const d = new Date( e.MeasureDate ); 
    return d.getTime() == mostRecentDate.getTime();
);

这也提高了代码的性能,因为它会在找到结果后停止查找,而不是过滤器,它会遍历数组中的所有对象。

【讨论】:

【参考方案7】:

受此线程中许多建议和 cmets 的启发,这里是该问题的另一种解决方案。它非常快,因为没有日期对象转换。

function getLatestDate(xs) 
   if (xs.length) 
      return xs.reduce((m, i) => (i.MeasureDate > m) && i || m, "")
               .MeasureDate;
   
 

这是浏览器不支持箭头功能的版本:

function getLatestDateSave(xs) 
   if (xs.length) 
      return xs.reduce(function(m, i) 
         return (i.MeasureDate > m) && i || m;
      , "").MeasureDate;
   
 

【讨论】:

您使用的是哪个浏览器?也许它不支持箭头功能喷射。在此处查看更多详细信息:developer.mozilla.org/de/docs/Web/JavaScript/Reference/… 添加了一个 我正在使用带有 Angular 5 的 getLatestDate() 版本。适用于最新的 Opera、Chrome、Safari、Firefox。【参考方案8】:

这就是我选择最新/最高日期的方式

var maxLastseen= obj.sort((a,b) => new Date(b.lastS).getTime() - new Date(a.lastS).getTime())[0];

【讨论】:

【参考方案9】:
        var dates = []; 

        dates.push(new Date("2019/06/25")); 
        dates.push(new Date("2019/06/26")); 
        dates.push(new Date("2019/06/27")); 
        dates.push(new Date("2019/06/28")); 

        function GFG_Fun()  
            var maximumDate=new Date(Math.max.apply(null, dates)); 
            var minimumDate=new Date(Math.min.apply(null, dates)); 
         

【讨论】:

欢迎来到 SO。请你解释一下为什么这是答案。 我更新了它并使其尽可能简单。这是从我个人使用的日期数组中获取最大或最小日期的最佳方法。 @IdreesRamzan 在对象中,不在数组中【参考方案10】:

按表现评分的答案:

    data.reduce((a, b) =&gt; a.MeasureDate &gt; b.MeasureDate ? a : b).MeasureDate data.map(e =&gt; e.MeasureDate).reduce((a, b) =&gt; a &gt; b ? a : b) new Date(Math.max.apply(null, data.map(e =&gt; new Date(e.MeasureDate)))).toISOString()

(假设 x 是数组)

【讨论】:

以上是关于从客户端的对象数组中获取最新日期的优雅方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章

java 将服务器上读取到的返回给客户端的方法?

将巨大的 JS 对象带到客户端的最佳方法是啥? [关闭]

获取数组中对象的值

将文件从 REST Web 服务发送到客户端的正确方法是啥?

如何从 MongoDB 中的数组中查询具有最新日期的对象?

如何从对象集合中获取第二个最新日期的对象