如何结合start_time与end_time将对象数组按1小时时间区间分组
JS实现按整点小时区间同时参考起止时间分组对象数组
实现逻辑
默认分组规则为:只要数据的start_time到end_time的时间区间,和任意整点1小时区间存在重叠,就将该数据归入对应分组。如果你的实际规则是「数据完全落在小时区间内」「仅数据起始时间落在区间内」等,可以自行调整重叠判断条件。
实现步骤:
- 封装获取单个时间所属整点区间key的方法
- 对每一条数据,计算它的起止时间分别落在哪个整点区间
- 遍历该数据覆盖的所有整点区间,将数据添加到对应分组中
完整代码示例
// 获取指定时间对应的整点区间key,格式为「H-H+1」 const createRangeKey = (timeStr) => { const hour = new Date(timeStr).getHours(); return `${hour}-${hour + 1}`; }; // 判断两个时间区间是否有重叠 const isOverlap = (interval1Start, interval1End, interval2Start, interval2End) => { return interval1Start < interval2End && interval2Start < interval1End; }; // 按整点小时区间分组的主逻辑 const groupByHourRange = (data) => { return data.reduce((result, item) => { const itemStart = new Date(item.start_time).getTime(); const itemEnd = new Date(item.end_time).getTime(); // 计算数据起止时间对应的整点小时数 const startHour = new Date(item.start_time).getHours(); const endHour = new Date(item.end_time).getHours(); const isSameDay = new Date(item.start_time).toDateString() === new Date(item.end_time).toDateString(); // 处理同一天的区间 if (isSameDay) { for (let hour = startHour; hour <= endHour; hour++) { const currRangeStart = new Date(item.start_time).setHours(hour, 0, 0, 0); const currRangeEnd = new Date(item.start_time).setHours(hour + 1, 0, 0, 0); if (isOverlap(itemStart, itemEnd, currRangeStart, currRangeEnd)) { const key = `${hour}-${hour + 1}`; if (!result[key]) result[key] = []; result[key].push(item); } } } else { // 跨天场景:先处理当天剩余小时,再处理第二天的小时,可根据需求调整key格式拼接日期避免分组冲突 for (let hour = startHour; hour <= 23; hour++) { const currRangeStart = new Date(item.start_time).setHours(hour, 0, 0, 0); const currRangeEnd = new Date(item.start_time).setHours(hour + 1, 0, 0, 0); if (isOverlap(itemStart, itemEnd, currRangeStart, currRangeEnd)) { const key = `${hour}-${hour + 1}`; if (!result[key]) result[key] = []; result[key].push(item); } } for (let hour = 0; hour <= endHour; hour++) { const currRangeStart = new Date(item.end_time).setHours(hour, 0, 0, 0); const currRangeEnd = new Date(item.end_time).setHours(hour + 1, 0, 0, 0); if (isOverlap(itemStart, itemEnd, currRangeStart, currRangeEnd)) { const key = `${hour}-${hour + 1}`; if (!result[key]) result[key] = []; result[key].push(item); } } } return result; }, {}); }; // 使用示例 const result = groupByHourRange(yourDataArray);
扩展说明
- 如果需要避免跨天数据的分组冲突,可以把key的格式改成
YYYY-MM-DD H-H+1,修改key生成逻辑拼接日期即可 - 如果你的分组规则是仅将数据归入包含它最长重叠时长的小时区间,可以在遍历区间时计算重叠时长,最后只加到最长的那个分组里
内容的提问来源于stack exchange,提问作者madhubala
相关产品推荐
相关产品推荐

