如何在Javascript中从数组中返回最小日期值和最大日期值?

3

如何从数组中返回最早和最晚的日期值?

例如,针对下面的数组,我想创建一个返回最早日期的函数以及另一个返回最晚日期的函数:

var data = [
  {date: "2011-11-01T16:17:54Z", quantity: 2, total: 190, tip: 100, type: "tab"},
  {date: "2011-11-14T16:20:19Z", quantity: 2, total: 190, tip: 100, type: "tab"},
  {date: "2011-11-14T16:28:54Z", quantity: 1, total: 300, tip: 200, type: "visa"},
  {date: "2011-11-14T16:30:43Z", quantity: 2, total: 90, tip: 0, type: "tab"},
  {date: "2011-11-14T16:48:46Z", quantity: 2, total: 90, tip: 0, type: "tab"},
  {date: "2011-11-14T16:53:41Z", quantity: 2, total: 90, tip: 0, type: "tab"},
  {date: "2011-11-14T16:54:06Z", quantity: 1, total: 100, tip: 0, type: "cash"},
  {date: "2011-11-14T16:58:03Z", quantity: 2, total: 90, tip: 0, type: "tab"},
  {date: "2011-11-14T17:07:21Z", quantity: 2, total: 90, tip: 0, type: "tab"},
  {date: "2011-11-14T17:22:59Z", quantity: 2, total: 90, tip: 0, type: "tab"},
  {date: "2011-11-14T17:25:45Z", quantity: 2, total: 200, tip: 0, type: "cash"},
  {date: "2011-11-31T17:29:52Z", quantity: 1, total: 200, tip: 100, type: "visa"}
]; 

我不确定这是否相关,但我正在使用这个数组与crossfilter一起使用,因此我不确定crossfilter是否有任何有用的方法。


1
数组总是按那种顺序排列吗?因为那样的话,你可以简单地返回第一个或最后一个。 - Vincent Beltman
2
那个最后的日期无法正确转换为日期。 - Andy
你可以对数组进行排序,然后获取上限和下限。看一下这个答案:**按日期排序Javascript对象数组**。 - jherax
6个回答

6

我们只需要应用一些Javascript 魔法

var result = Math.max.apply( null, data.map(function( v ) {
    return +new Date( v.date );
}));

在这里,我们将这些对象映射为仅从ISO-Date字符串中表示它们的时间戳。然后我们只需对结果数组应用Math.maxMath.min即可。现在我们所要做的就是将该时间戳重新转换为日期对象。

new Date( result );

为了好玩,这里提供一个使用Array.prototype.reduce和纯字符串比较的替代解决方案(如果您担心浏览器在解析ISO日期字符串时不兼容)。

var max = data.reduce(function( prev, current ) {
  return prev.date > current.date ? prev : current;
});
// for the min version just ">" to "<"

@Andy 我刚刚意识到,最后一条记录似乎有点不对劲。 - jAndy
一个不错的答案。然而,在循环内执行简单的字符串比较也可以得到原问题的期望结果。 - user1741851
1
@Andy 我打赌你也喜欢升级版的Magic! - jAndy
我们从不使用Date构造函数来解析日期字符串,因为这样做本质上是不可靠的(例如,IE 8将返回NaN,当给定ES5规范中指定的格式时)。 ISO 8601日期字符串按预期排序,因此根本不需要转换为Date。 - RobG
@RobG 很有趣。您对使用比较运算符比较(日期)字符串的浏览器兼容性有多大把握? - jAndy
显示剩余9条评论

2
您可以使用自定义比较器来对数组进行排序:
data.sort(function(o1,o2){
    return new Date(o1.date).getTime() - new Date(o2.date).getTime();
});

然后通过获取第一个/最后一个项目来获取最大/最小日期:

var smallest = data[0].date;
var largest  = data[data.length - 1].date;

您IP地址为143.198.54.68,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。 - jherax

1
一个简单的字符串比较应该可以给你期望的结果。由于日期是以ISO字符串格式表示的,所以这应该相当容易做到。
var lowestIndex = 0;
var lowestDate = data[0].date;
for (var i=0; i<data.length; i++) {
    if (lowestDate > data[i].date) {
        lowestDate = data[i].date;
        lowestIndex = i;
    }
}
return data[lowestIndex];

如果你熟悉applycall,那么将这个简单的逻辑转换为一个函数应该不会有太多麻烦。

0
你可以按这些键进行排序,然后取第一个和最后一个值:
sortedData = data.sort(function(a, b) {
    return new Date(a.date) > new Date(b.date) ? 1 : -1;
});
var min = sortedData[0],
    max = sortedData[sortedData.length - 1];

0

有很多建议将字符串转换为日期,但是使用Date构造函数解析字符串是不可靠的,并且即使对于ES5中指定的格式,在使用的浏览器中也会失败。

由于您正在使用ISO 8601格式的日期字符串,因此可以在不进行转换的情况下对其进行排序(这是使用该格式的好处之一,以及它的明确性)。因此,您可以使用以下方式对数组进行排序:

data.sort(function(a, b) {return a.date > b.date? 1 : a.date < b.date? -1 : 0});

现在你只需要获取数组的第一个和最后一个成员:

var earliestDate = data[0].date;
var latestDate   = data[data.length - 1].date;

正如其他人所说,最后一个日期字符串是无效的日期,排序应该如何处理?上面的建议并没有测试日期是否有效,它只是查看字符。


好的,但是将所有日期排序以仅获取最低和最高日期并不是效率最高的做法。 - Joel

0

试试这个:

var data = [
  {date: "2011-11-01T16:17:54Z", quantity: 2, total: 190, tip: 100, type: "tab"},
  {date: "2011-11-14T16:20:19Z", quantity: 2, total: 190, tip: 100, type: "tab"},
  {date: "2011-11-14T16:28:54Z", quantity: 1, total: 300, tip: 200, type: "visa"},
  {date: "2011-11-14T16:30:43Z", quantity: 2, total: 90, tip: 0, type: "tab"},
  {date: "2011-11-14T16:48:46Z", quantity: 2, total: 90, tip: 0, type: "tab"},
  {date: "2011-11-14T16:53:41Z", quantity: 2, total: 90, tip: 0, type: "tab"},
  {date: "2011-11-14T16:54:06Z", quantity: 1, total: 100, tip: 0, type: "cash"},
  {date: "2011-11-14T16:58:03Z", quantity: 2, total: 90, tip: 0, type: "tab"},
  {date: "2011-11-14T17:07:21Z", quantity: 2, total: 90, tip: 0, type: "tab"},
  {date: "2011-11-14T17:22:59Z", quantity: 2, total: 90, tip: 0, type: "tab"},
  {date: "2011-11-14T17:25:45Z", quantity: 2, total: 200, tip: 0, type: "cash"},
  {date: "2011-11-31T17:29:52Z", quantity: 1, total: 200, tip: 100, type: "visa"}
];

var lowest = data.reduce(function (a, b) {
    var timeA = new Date(a.date).getTime();
    var timeB = new Date(b.date).getTime();
    return timeA < timeB ? a : b;
});

alert("lowest: " + JSON.stringify(lowest, null, 4));

var highest = data.reduce(function (a, b) {
    var timeA = new Date(a.date).getTime();
    var timeB = new Date(b.date).getTime();
    return timeA > timeB ? a : b;
});

alert("highest: " + JSON.stringify(highest, null, 4));


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接