如何用moment.js和lodash.js实现时间按5分钟间隔优雅分组?
实现方案
核心思路
先对时间数组做升序排序,再通过单次遍历完成分组:判断当前时间与当前分组的最晚时间差值是否≤5分钟,符合则加入当前分组,否则新开分组。整个过程只需要1次排序+1次遍历,时间复杂度为O(nlogn)(主要来自排序开销),比多次迭代的效率更高也更易读。
代码实现(支持moment.js)
const moment = require('moment'); const startTime = [ '2021-09-30T02:38:56', '2021-09-30T02:39:56', '2021-09-30T02:40:56', '2021-09-30T02:10:56', '2021-09-30T02:11:56' ]; // 时间升序排序 const sortedTimes = [...startTime].sort((a, b) => moment(a).valueOf() - moment(b).valueOf()); // 按时间差分组 const timeGroups = sortedTimes.reduce((groups, curTime) => { if (!groups.length) return [[curTime]]; const lastGroup = groups.at(-1); const lastGroupTime = lastGroup.at(-1); const diffMin = moment(curTime).diff(lastGroupTime, 'minutes'); diffMin <= 5 ? lastGroup.push(curTime) : groups.push([curTime]); return groups; }, []); // 如需要和示例输出顺序一致(时间大的分组在前),打开下方注释 // timeGroups.reverse() console.log(timeGroups)
结合lodash简化写法
如果项目中已经引入lodash,可以用_.sortBy简化排序逻辑:
const _ = require('lodash'); const moment = require('moment'); const timeGroups = _.reduce( _.sortBy(startTime, t => moment(t).valueOf()), (groups, curTime) => { if (!groups.length) return [[curTime]]; const lastGroup = groups.at(-1); moment(curTime).diff(lastGroup.at(-1), 'minutes') <=5 ? lastGroup.push(curTime) : groups.push([curTime]); return groups; }, [] )
补充说明
- 如果你的需求是分组内所有时间和组内最早时间的差值不超过5分钟,只需要把对比的
lastGroup.at(-1)改成lastGroup[0]即可。 - 如果你不想依赖moment,也可以直接用原生Date计算时间差:
(new Date(curTime) - new Date(lastGroupTime)) / 1000 / 60,得到的就是分钟差值。
内容的提问来源于stack exchange,提问作者ramamoorthy_villi
相关产品推荐
相关产品推荐

