如何从数组中返回最低日期值和最高日期值?
例如,对于下面的数组,我想创建一个返回最低日期的函数,以及另一个返回最高日期的函数?
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是否有任何有用的方法。
答案 0 :(得分:6)
我们只需要应用一些Javascript Magic。
var result = Math.max.apply( null, data.map(function( v ) {
return +new Date( v.date );
}));
在那里,我们将这些对象映射到ISO-Date字符串中的时间戳表示。然后我们只在结果数组上分别应用Math.max
Math.min
。我们现在要做的就是将该时间戳重新转换为Date对象
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 "<"
答案 1 :(得分:1)
您可以使用自定义比较器对数组进行排序:
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;
答案 2 :(得分: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];
如果您对apply
和call
感到满意,那么将这个简单的逻辑转换为函数应该不会有太多麻烦。
答案 3 :(得分: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];
答案 4 :(得分: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));
答案 5 :(得分: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;
正如其他人所说,最后一个日期字符串是无效日期,排序应如何处理?上述建议不测试日期是否有效,只是查看字符。