使用Lodash和Moment按月份分组日期并降序排序的问题
解决按月份分组并降序排序的问题
你的分组逻辑其实没毛病,但_.groupBy返回的是一个普通对象——早期JS里对象的键是无序的,哪怕现在ES6+保留了插入顺序,它也不会自动帮你按月份降序排列。所以得加几步处理,才能得到你想要的有序结果。
完整实现代码
const data = [ { "modDate": "2017-06-20" }, { "modDate": "2017-10-24" }, { "modDate": "2017-08-03" } ]; // 第一步:按月份分组,用YYYY/MM作为分组键(你的原逻辑是对的) const groupedData = _.groupBy(data, item => moment(item.modDate).startOf('month').format('YYYY/MM')); // 第二步:提取所有月份键,按降序排序 const sortedMonthKeys = Object.keys(groupedData).sort((a, b) => b.localeCompare(a)); // 第三步:构建有序结果,这里提供两种常用形式: // 形式1:返回数组(推荐,遍历顺序绝对可控) const sortedResultArray = sortedMonthKeys.map(month => ({ month: month, items: groupedData[month] })); // 形式2:返回有序对象(ES6+支持,键会保持排序后的顺序) const sortedResultObject = Object.fromEntries( sortedMonthKeys.map(month => [month, groupedData[month]]) ); console.log(sortedResultArray);
关键步骤说明
- 分组逻辑:你原来用
moment处理日期并格式化的方式完全正确,能精准把同一月份的条目归到同一组。 - 排序键值:
Object.keys(groupedData)拿到所有月份字符串,用b.localeCompare(a)实现降序——因为YYYY/MM格式的字符串可以直接按字典序比较大小(比如"2017/10"肯定比"2017/08"大),排序逻辑很可靠。 - 结果整理:
- 数组形式的结果最稳妥,遍历的时候绝对是按降序来的,适合后续渲染或处理;
- 对象形式适合需要保持键值对结构的场景,ES6+环境下会严格保留排序后的键顺序。
最终输出示例
运行代码后,sortedResultArray会输出:
[ { month: '2017/10', items: [ { modDate: '2017-10-24' } ] }, { month: '2017/08', items: [ { modDate: '2017-08-03' } ] }, { month: '2017/06', items: [ { modDate: '2017-06-20' } ] } ]
完美符合你“先分组、再按月份降序排序”的需求~
内容的提问来源于stack exchange,提问作者croppio.com
相关产品推荐
相关产品推荐

