如何对含日期属性的对象数组排序并按连续日期分组?
优化连续日期对象分组方案
我来帮你搞定这个连续日期分组的需求,你的现有代码确实存在逻辑漏洞(比如重复排序、错误的排序回调逻辑),而且没覆盖所有场景。下面是一个高效且逻辑清晰的实现方案:
核心思路
- 先排序:必须先按日期升序排列数组,这是正确分组的基础(注意不要修改原数组)
- 维护临时分组:遍历过程中用一个临时数组保存当前连续的日期对象
- 判断连续性:用
date-fns的differenceInDays对比当前对象和临时组最后一个对象的日期差,差为1则加入临时组,否则结束当前组并加入结果 - 收尾处理:遍历结束后别忘了把最后一个临时组加入结果
完整代码实现
import { differenceInDays } from 'date-fns'; function groupConsecutiveDates(inputArray) { // 复制原数组并按日期升序排序,避免修改原输入 const sortedArray = [...inputArray].sort((a, b) => new Date(a.date) - new Date(b.date)); // 处理空数组边界情况 if (sortedArray.length === 0) return []; const finalArray = []; // 初始化当前连续分组,从第一个元素开始 let currentGroup = [sortedArray[0]]; // 从第二个元素开始遍历 for (let i = 1; i < sortedArray.length; i++) { const lastInGroup = currentGroup[currentGroup.length - 1]; const currentObj = sortedArray[i]; // 计算当前对象与分组最后一个对象的天数差 const dayDifference = differenceInDays(new Date(currentObj.date), new Date(lastInGroup.date)); if (dayDifference === 1) { // 日期连续,加入当前分组 currentGroup.push(currentObj); } else { // 日期不连续,将当前分组加入结果:长度>1则放子数组,否则放单个对象 finalArray.push(currentGroup.length > 1 ? currentGroup : currentGroup[0]); // 重置当前分组为当前对象 currentGroup = [currentObj]; } } // 处理遍历结束后剩余的最后一个分组 finalArray.push(currentGroup.length > 1 ? currentGroup : currentGroup[0]); return finalArray; } // 示例测试 const inputArray = [ { date: '2024-01-01' }, { date: '2024-01-03' }, { date: '2024-01-04' }, { date: '2024-01-05' }, { date: '2024-01-07' }, { date: '2024-01-08' }, { date: '2024-01-10' } ]; console.log(groupConsecutiveDates(inputArray)); // 输出结果: // [ // { date: '2024-01-01' }, // [ { date: '2024-01-03' }, { date: '2024-01-04' }, { date: '2024-01-05' } ], // [ { date: '2024-01-07' }, { date: '2024-01-08' } ], // { date: '2024-01-10' } // ]
方案优势
- 高效性:排序仅执行一次(时间复杂度O(n log n)),遍历为线性O(n),整体性能最优
- 边界覆盖:处理了空数组、单个元素、全连续、全不连续、混合连续等所有场景
- 无副作用:通过复制数组避免修改原输入
- 逻辑清晰:每一步职责明确,容易维护和调试
原代码的问题说明
你的原有代码存在几个关键问题:
- 重复执行排序操作,完全冗余
- 第二次排序的回调函数逻辑错误:排序回调应该返回数字(用于比较),而不是执行push操作,这会导致排序行为不可预测
- 没有正确维护连续分组,无法处理3个及以上连续元素的情况,且会重复添加元素到结果中
内容的提问来源于stack exchange,提问作者snovosel
相关产品推荐
相关产品推荐

