如何在 Javascript 中按 15 分钟的间隔对 json 集合进行分组

Sté*_*car 2 javascript arrays grouping

假设我们在 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' }
]
Run Code Online (Sandbox Code Playgroud)

我想找到一个优雅的算法来按“最近”日期按这个数组分组。如果日期在前一个日期之前或之后 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' }
    ]
]
Run Code Online (Sandbox Code Playgroud)

我尝试使用 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});
});
Run Code Online (Sandbox Code Playgroud)

Pau*_*aul 7

从 tjdett 的 UnderscoreJS 代码开始,逐年提问

var dateGroups = _.chain(objarray)
                  .groupBy(function(obj) { return obj.date.getFullYear(); })
                  .sortBy(function(v, k) { return k; })
                  .value();
Run Code Online (Sandbox Code Playgroud)

您可以使用为 15 分钟而不是年设计的 groupBy 函数尝试相同的解决方案,return Math.floor(+(obj.date)/(1000*60*15));此返回语句用于+将 Date 对象转换为毫秒数(自纪元以来),然后除以 1000*60*15 为 15Math.floor()丢弃分数的分钟间隔。

为此,obj.date 必须是 Date 类型。如果您的日期只是字符串,您可能首先需要从这些字符串中解析年、月、日、小时、分钟,然后构造一个新的 Date 对象

这将创建绝对 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
Run Code Online (Sandbox Code Playgroud)