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

TypeScript如何按枚举定义顺序而非字母序对对象数组排序

字符串枚举按定义顺序排序的实现方案

现有问题根源

TypeScript的字符串枚举编译为JavaScript后,仅会保留「枚举键-枚举字符串值」的映射关系,不会内置成员的定义顺序属性。当前使用sortBy直接返回对象的code字符串值作为排序键时,排序逻辑会默认按字符串的字典ASCII序做比较,因此会出现FIXTERM_1M排在FIXTERM_2W前面的异常顺序,和业务要求的枚举定义顺序不一致。

具体实现步骤

1. 建立枚举排序权重映射

排序的核心逻辑是给每个枚举值分配一个对应定义顺序的数字权重,数字越小越靠前。
有两种映射生成方式可选:

  • 手动维护映射(适合枚举成员基本固定的场景):直接按照代码里定义MyEnum的先后顺序,为每个枚举值分配连续的索引值:
    const ENUM_SORT_ORDER: Record<MyEnum, number> = {
      [MyEnum.FIXTERM1W]: 0,
      [MyEnum.FIXTERM2W]: 1,
      [MyEnum.FIXTERM1M]: 2,
      [MyEnum.FIXTERM2M]: 3,
      [MyEnum.FIXTERM3M]: 4,
      [MyEnum.FIXTERM6M]: 5,
      [MyEnum.FIXTERM1Y]: 6,
      [MyEnum.FIXTERMDEFAULT]: 7,
      [MyEnum.FIXTERMWA]: 8,
      [MyEnum.ONCALL24H]: 9,
      [MyEnum.ONCALL48H]: 10,
      [MyEnum.ONCALLWA]: 11
    };
    
  • 动态生成映射(适合枚举后续会新增成员的场景):利用JavaScript非整数索引的字符串键对象按插入顺序遍历的特性,直接从编译后的枚举对象中提取顺序,无需手动维护:
    const ENUM_SORT_ORDER: Record<string, number> = Object.values(MyEnum)
      .reduce((acc, cur, index) => ({ ...acc, [cur]: index }), {});
    
    该方式生成的映射顺序和枚举的定义顺序完全一致,后续新增、调整枚举成员顺序时,映射会自动同步,不需要额外维护。

2. 替换原有排序逻辑

把原来排序函数里返回o.code的逻辑,替换为返回映射表中对应的权重值,同时增加兜底逻辑:万一遇到不在映射表中的枚举值,统一分配最大权重值,排到数组末尾,避免排序报错。
修改后的xxx getter代码如下:

get xxx(): Yyyy {
  if (this._myvalue && this._myvalue.myobject && this._myvalue.myobject.length > 0) {
    this._myvalue.myobject = sortBy(this._myvalue.myobject,
      (o: myobject) => ENUM_SORT_ORDER[o.code] ?? Number.MAX_SAFE_INTEGER
    );
  }
  return this._myvalue;
}

效果说明

调整后的排序逻辑会完全按照枚举的定义顺序排列数组元素,最终得到的序列就是业务期望的FIXTERM_1W → FIXTERM_2W → FIXTERM_1M → FIXTERM_2M ...的顺序,不会再出现按字符串字典序乱排的问题。


内容的提问来源于stack exchange,提问作者Haifisch

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.22 14:15:04