You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何按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;
});

代码说明

  1. 数组副本:用[...data]复制原数组,避免修改原始数据
  2. fYear优先级映射:通过对象给每个fYear分配权重,确保排序顺序符合需求
  3. FQtr排序逻辑:提取FQtr中W后的字符串转为整数,用数字差实现自然升序
  4. 边界处理: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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 03:45:38