问题描述
假设我们在Javascript中有一个这样的集合:
Let say we have a collection like this in 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分钟,则会将其推入同一对象中.
I would like to to find an elegant algorithm to group by this array by "closest" date. If a date is 15 minutes before or after a previous date, it will be pushed in the same object.
我真的不关心子数组的结构如何.此项的结果可能是:
I doesn't really matter how the sub-array will be structured. The result for this entry could be:
[
[
{ 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并没有获得真正的成功:
I have try without real success using 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});
});
推荐答案
从tjdett的年份问题:
var dateGroups = _.chain(objarray)
.groupBy(function(obj) { return obj.date.getFullYear(); })
.sortBy(function(v, k) { return k; })
.value();
您可以使用设计为15分钟间隔(而不是年份)的groupBy函数使用return Math.floor(+(obj.date)/(1000*60*15));
尝试相同的解决方案,并使用return Math.floor(+(obj.date)/(1000*60*15));
.此return语句使用+
将Date对象转换为毫秒数(从纪元开始),然后除以1000 * 60 * 15间隔15分钟,Math.floor()
丢弃该分数.
You could try this same solution with a groupBy function designed for 15 minute intervals instead of years, with return Math.floor(+(obj.date)/(1000*60*15));
This return statement uses +
to convert the Date object to a number of milliseconds (since epoch), and then divides by 1000*60*15 for 15 minute intervals with Math.floor()
discarding the fraction.
要使其正常工作,obj.date必须为Date类型.如果您的日期只是字符串,则可能需要先解析年,月,日,这些字符串中的小时,分钟,然后构造一个新的Date对象.
For that to work, obj.date must be type Date. If your dates are just strings, you may first need to 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分钟内.
This will create absolute 15 minute clock blocks, i.e. 01:00:00-01:14:59.9999, 01:15:00-01:29:59.9999; not 15 minutes that begin with new activity.
因此,如果您要从新数据开始的一组15分钟的数据,则需要创建groupBy函数,并保持关闭状态,即当前组的结束时间,以便可以启动新组,并且需要从按日期排序的对象中获取数据,以便首先进行排序.
So if you want a group of 15 minutes of data that starts with new data, the groupBy function would need to be created with a closure retaining state of when the current group ends so that new groups could be started, and it would need to be fed from objects sorted by date, so that a sort needs to happen first.
这听起来像是鲁伯-戈德堡(Rube-Goldbergish),并且可能更容易直接这样做(未经测试)
That sounds Rube-Goldbergish, and might be easier to do directly like this (untested):
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
这篇关于如何按15分钟间隔对Javascript中的json集合进行分组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!