JavaScript中按双键对结构化对象分组并排序的问题
解决分组后遍历顺序不确定的问题
因为Object.groupBy返回的是普通对象,其键的顺序由元素在原数组中首次出现的顺序决定,无法直接保证符合WeekNumber和TeeOff的排序需求。可以通过两种思路解决:
思路1:先排序原数组,再分组
先对原数组按WeekNumber(优先)和TeeOff排序,再执行分组操作。由于Object.groupBy会保留原数组的插入顺序,分组后的键顺序会自动符合排序规则。
// 复制原数组避免修改原数据,然后排序 const sortedSchedule = [...weeklySchedule].sort((a, b) => { // 先按WeekNumber数值排序 const weekDiff = a.WeekNumber - b.WeekNumber; if (weekDiff !== 0) { return weekDiff; } // 周数相同时,按TeeOff排序(假设TeeOff是ISO时间字符串,若为数字直接用a.TeeOff - b.TeeOff) return new Date(a.TeeOff) - new Date(b.TeeOff); }); // 按WeekNumber+TeeOff组合分组 const grouped = Object.groupBy(sortedSchedule, item => `${item.WeekNumber}-${item.TeeOff}`); // 此时遍历分组的键,顺序就是排序后的结果 for (const key of Object.keys(grouped)) { const [weekNum, teeOff] = key.split('-'); console.log(`第${weekNum}周,开球时间:${teeOff}`, grouped[key]); }
思路2:先分组,再对分组键排序
如果不想修改原数组,可以先完成分组,再提取所有分组键,按规则排序后遍历。
// 先执行分组 const grouped = Object.groupBy(weeklySchedule, item => `${item.WeekNumber}-${item.TeeOff}`); // 提取分组键并按规则排序 const sortedKeys = Object.keys(grouped).sort((keyA, keyB) => { const [weekA, teeA] = keyA.split('-'); const [weekB, teeB] = keyB.split('-'); // 优先比较WeekNumber const weekCompare = Number(weekA) - Number(weekB); if (weekCompare !== 0) { return weekCompare; } // 再比较TeeOff,根据实际类型调整(示例为时间字符串) return new Date(teeA) - new Date(teeB); }); // 按排序后的键遍历分组 sortedKeys.forEach(key => { const group = grouped[key]; // 处理分组数据,比如渲染、计算等 });
分层分组场景(先按周,再按开球时间)
如果需要先按WeekNumber分成大组,每个大组内再按TeeOff分小组,同样可以用排序+分层分组的方式:
// 先按WeekNumber分组 const groupedByWeek = Object.groupBy(weeklySchedule, item => item.WeekNumber); // 对周数键排序 const sortedWeekKeys = Object.keys(groupedByWeek).sort((a, b) => Number(a) - Number(b)); // 遍历排序后的周数,再对每个周的组按TeeOff分组并排序 sortedWeekKeys.forEach(weekKey => { const weekData = groupedByWeek[weekKey]; const groupedByTee = Object.groupBy(weekData, item => item.TeeOff); // 对开球时间键排序 const sortedTeeKeys = Object.keys(groupedByTee).sort((a, b) => new Date(a) - new Date(b)); sortedTeeKeys.forEach(teeKey => { console.log(`第${weekKey}周,开球时间:${teeKey}`, groupedByTee[teeKey]); }); });
内容的提问来源于stack exchange,提问作者LarryBud
相关产品推荐
相关产品推荐

