如何按fYear与FQtr属性对JavaScript对象数组排序?
按fYear和FQtr对JavaScript对象数组排序的解决方案
需求说明
需要对包含fYear和FQtr字段的对象数组做双层排序:
- 第一层按
fYear排序:FY22 Q3→FY22 Q4→QTD - 第二层在同一
fYear下,按FQtr的数字部分升序排列(如W2排在W10之前)
原始数据
const data = [ { "fYear": "FY22 Q3", "FQtr": "W10"}, { "fYear": "FY22 Q3", "FQtr": "W11"}, { "fYear": "FY22 Q3", "FQtr": "W12"}, { "fYear": "FY22 Q3", "FQtr": "W13"}, { "fYear": "FY22 Q3", "FQtr": "W2"}, { "fYear": "FY22 Q4", "FQtr": "W1"}, { "fYear": "FY22 Q3", "FQtr": "W3"}, { "fYear": "FY22 Q3", "FQtr": "W4"}, { "fYear": "FY22 Q4", "FQtr": "W2"}, { "fYear": "FY22 Q3", "FQtr": "W5"}, { "fYear": "FY22 Q3", "FQtr": "W6"}, { "fYear": "FY22 Q3", "FQtr": "W7"}, { "fYear": "FY22 Q3", "FQtr": "W8"}, { "fYear": "FY22 Q3", "FQtr": "W9"}, { "fYear": "FY22 Q4", "FQtr": "W4"}, { "fYear": "QTD", "FQtr": "QTD"}, { "fYear": "FY22 Q4", "FQtr": "W3"} ]
期望排序结果
const sortedData = [ { "fYear": "FY22 Q3", "FQtr": "W2"}, { "fYear": "FY22 Q3", "FQtr": "W3"}, { "fYear": "FY22 Q3", "FQtr": "W4"}, { "fYear": "FY22 Q3", "FQtr": "W5"}, { "fYear": "FY22 Q3", "FQtr": "W6"}, { "fYear": "FY22 Q3", "FQtr": "W7"}, { "fYear": "FY22 Q3", "FQtr": "W8"}, { "fYear": "FY22 Q3", "FQtr": "W9"}, { "fYear": "FY22 Q3", "FQtr": "W10"}, { "fYear": "FY22 Q3", "FQtr": "W11"}, { "fYear": "FY22 Q3", "FQtr": "W12"}, { "fYear": "FY22 Q3", "FQtr": "W13"}, { "fYear": "FY22 Q4", "FQtr": "W1"}, { "fYear": "FY22 Q4", "FQtr": "W2"}, { "fYear": "FY22 Q4", "FQtr": "W3"}, { "fYear": "FY22 Q4", "FQtr": "W4"}, { "fYear": "QTD", "FQtr": "QTD"} ]
初步思路(已整合优化)
function sortFQtr( a, b ) { const [prevVal, nextVal] = [Number.parseInt(a.FQtr.substring(1)), Number.parseInt(b.FQtr.substring(1))]; if ( prevVal < nextVal ) return -1; if ( prevVal > nextVal) return 1; return 0; } // ["FY22 Q4", "FY22 Q3", "QTD"] var fYears = data.map(value => value.fYear).filter( (value, index, _arr) => _arr.indexOf(value) == index);
完整实现方案
将fYear优先级判断与FQtr数字排序整合到同一个排序函数中,确保逻辑连贯:
const sortedData = [...data].sort((a, b) => { // 手动定义fYear的排序优先级,按需求顺序分配权重 const yearPriority = { "FY22 Q3": 0, "FY22 Q4": 1, "QTD": 2 }; // 先比较fYear的权重差,非0则直接返回排序结果 const yearDiff = yearPriority[a.fYear] - yearPriority[b.fYear]; if (yearDiff !== 0) { return yearDiff; } // 同一fYear下,处理FQtr的数字排序(QTD无需处理) if (a.fYear !== "QTD") { const qtrA = parseInt(a.FQtr.slice(1), 10); const qtrB = parseInt(b.FQtr.slice(1), 10); return qtrA - qtrB; } return 0; });
代码说明
- 数组副本:用
[...data]复制原数组,避免修改原始数据 - fYear优先级映射:通过对象给每个
fYear分配权重,确保排序顺序符合需求 - FQtr排序逻辑:提取
FQtr中W后的字符串转为整数,用数字差实现自然升序 - 边界处理:QTD项单独跳过数字比较,因为它只有唯一一项
扩展优化(支持任意FYxx Qx格式)
如果后续有更多年份季度类型,可自动解析FYxx Qx格式,无需手动维护优先级:
const getYearQuarterWeight = (yearStr) => { if (yearStr === "QTD") return Infinity; // QTD固定排在最后 const [fyPart, qPart] = yearStr.split(" "); const yearNum = parseInt(fyPart.slice(2), 10); const quarterNum = parseInt(qPart.slice(1), 10); // 计算权重:年份*4 + 季度,确保FY22 Q3 < FY22 Q4 < FY23 Q1 return yearNum * 4 + quarterNum; }; const sortedData = [...data].sort((a, b) => { const weightA = getYearQuarterWeight(a.fYear); const weightB = getYearQuarterWeight(b.fYear); if (weightA !== weightB) { return weightA - weightB; } if (a.fYear !== "QTD") { const qtrA = parseInt(a.FQtr.slice(1), 10); const qtrB = parseInt(b.FQtr.slice(1), 10); return qtrA - qtrB; } return 0; });
内容的提问来源于stack exchange,提问作者Jeff
相关产品推荐
相关产品推荐

