假设我们在Javascript中有这样的集合:
[
{ date: 'Fri, 02 May 2014 19:05:00 GMT', value:'abc' },
{ date: 'Fri, 02 May 2014 23:43:00 GMT', value:'jkl' },
{ date: 'Fri, 02 May 2014 19:01:00 GMT', value:'def' },
{ date: 'Fri, 02 May 2014 19:09:00 GMT', value:'ghi' },
{ date: 'Fri, 02 May 2014 23:54:00 GMT', value:'mno' }
]
我想找到一个优雅的算法,通过这个数组分组,最近的"日期。如果日期是前一个日期之前或之后的15分钟,则它将被推送到同一个对象中。
我对子阵列的构造方式并不重要。此条目的结果可能是:
[
[
{ date: 'Fri, 02 May 2014 19:05:00 GMT', value:'abc' },
{ date: 'Fri, 02 May 2014 19:01:00 GMT', value:'def' },
{ date: 'Fri, 02 May 2014 19:09:00 GMT', value:'ghi' }
], [
{ date: 'Fri, 02 May 2014 23:43:00 GMT', value:'jkl' },
{ date: 'Fri, 02 May 2014 23:54:00 GMT', value:'mno' }
]
]
我使用underscore.js尝试没有真正的成功:
_.map(logs_by_date, function(group, date) {
return _.reduce(group, function(memo, elem) {
var moment = get_moment(elem);
memo[moment].push(elem);
return memo;
}, { 'date': date});
});
答案 0 :(得分:4)
从UnderscoreJS code from tjdett for a group-by-year question开始:
var dateGroups = _.chain(objarray)
.groupBy(function(obj) { return obj.date.getFullYear(); })
.sortBy(function(v, k) { return k; })
.value();
您可以尝试使用groupBy函数设置15分钟而不是几年的同一解决方案return Math.floor(+(obj.date)/(1000*60*15));
此返回语句使用+
将Date对象转换为毫秒数(自epoch起) ),然后除以1000 * 60 * 15,间隔15分钟,Math.floor()
丢弃分数。
要使其工作,obj.date必须是Date类型。如果您的日期只是字符串,则可能需要先parse the year, month, day, hour, minutes out of those strings and then construct a new Date object。
这将创建绝对的15分钟时钟块,即01:00:00-01:14:59.9999,01:15:00-01:29:59.9999;从新活动开始不是15分钟。
因此,如果您想要一组以新数据开头的15分钟数据,则需要创建groupBy函数,并保留当前组结束时的关闭保留状态,以便可以启动新组,并且需要从按日期排序的对象中提供,因此需要先进行排序。
这听起来像Rube-Goldbergish,并且可能更容易直接这样做(未经测试):
fixDates(objArray); // a function you'll write to turn your date strings into Date objects
function compareDates(a,b){ return (+a.date)-(+b.date); }
objArray.sort(compareDates); // sorts in place, array is changed
var groups = [], g=[], d=0;
for (var gx=+objArray[0].date+15*60*1000,i=0,l=objArray.length; i<l; ++i){
d = +(objArray[i].date);
if (d>gx){
groups.push(g);
g = [];
gx = +objArray[i].date+15*60*1000;
}
g.push(objArray[i]);
}
groups.push(g); // include last group otherwise unpushed
// result in groups