如何按月份分组同时保留年份排序顺序?
解决方案
要实现按月份分组且保留年份+月份的排序顺序,核心问题在于普通JavaScript对象的数字类型键会被自动按数值大小排序,直接用对象分组会打乱你想要的顺序。可以通过以下两种方式解决:
方法一:使用Map保持顺序
Map会严格按照键的插入顺序存储,完美匹配你需要的排序逻辑:
const arr = [ {month: 1, year: 2021}, {month: 2, year: 2021}, {month: 3, year: 2021}, {month: 3, year: 2021}, {month: 4, year: 2021}, {month: 9, year: 2020}, {month: 9, year: 2020}, {month: 10, year: 2020}, {month: 11, year: 2020}, {month: 12, year: 2020}, {month: 12, year: 2020}, ]; // 1. 先按年份+月份排序 const sortedArr = [...arr].sort((a, b) => { if (a.year !== b.year) return a.year - b.year; return a.month - b.month; }); // 2. 用Map分组,保留插入顺序 const groupedMap = new Map(); sortedArr.forEach(item => { const key = item.month; if (!groupedMap.has(key)) { groupedMap.set(key, []); } groupedMap.get(key).push(item); }); // 如需转成对象(注意:普通对象数字键仍会自动排序,建议直接用Map) const groupedObj = Object.fromEntries(groupedMap);
方法二:构建有序分组数组
如果你的图表更适配数组形式的分组数据,可以直接生成包含月份和对应数据的有序数组:
// 排序步骤同上 const sortedArr = [...arr].sort((a, b) => { if (a.year !== b.year) return a.year - b.year; return a.month - b.month; }); // 构建有序分组数组 const groupedArr = []; let currentMonth = null; let currentGroup = []; sortedArr.forEach(item => { if (item.month !== currentMonth) { if (currentGroup.length > 0) { groupedArr.push({ month: currentMonth, data: currentGroup }); } currentMonth = item.month; currentGroup = [item]; } else { currentGroup.push(item); } }); // 加入最后一组 if (currentGroup.length > 0) { groupedArr.push({ month: currentMonth, data: currentGroup }); }
注意事项
如果一定要用普通对象存储分组结果,由于JS引擎会自动对数字键排序,你看到的对象键顺序会是1,2,3,4,9,10...,无法实现你期望的9,10,11,12,1,2...顺序。这种情况下更推荐使用Map或者有序分组数组来适配图表展示需求。
内容的提问来源于stack exchange,提问作者Garrett Harty
相关产品推荐
相关产品推荐

