基于枚举常量的打字稿排序

ibe*_*beu 11 enums typescript

是否可以按照这些枚举的声明顺序对枚举列表进行排序?

enum MyEnum {
    VALUE_1,
    VALUE_3,
    VALUE_2
}
Run Code Online (Sandbox Code Playgroud)

我以随机顺序创建一个列表

let list = [MyEnum.VALUE_3, MyEnum.VALUE_1, MyEnum.VALUE_2];
Run Code Online (Sandbox Code Playgroud)

但是当枚举被声明时它被排序

[MyEnum.VALUE_1, MyEnum.VALUE_3, MyEnum.VALUE_2]
Run Code Online (Sandbox Code Playgroud)

PS:我真的很想知道 typescript 是否像我们在 Java 中那样直接订购列表,而不必自己订购。如果我必须自己订购列表,如果订单发生更改,我很容易出错。

Ric*_*Dev 22

刚才有同样的问题。这是我的解决方案:

enum Weekday {
  MONDAY = 'MONDAY',
  TUESDAY = 'TUESDAY',
  WEDNESDAY = 'WEDNESDAY',
  THURSDAY = 'THURSDAY',
  FRIDAY = 'FRIDAY',
  SATURDAY = 'SATURDAY',
  SUNDAY = 'SUNDAY'
}

const weekdayOrder = Object.values(Weekday);

const weekdaysToBeSorted = [Weekday.TUESDAY, Weekday.MONDAY, Weekday.FRIDAY];

const sortedWeekdays = weekdaysToBeSorted
  .sort((a, b) => weekdayOrder.indexOf(a) - weekdayOrder.indexOf(b))
Run Code Online (Sandbox Code Playgroud)


Nit*_*mer 8

如果您查看枚举的已编译 javascript:

var MyEnum;
(function (MyEnum) {
    MyEnum[MyEnum["VALUE_1"] = 0] = "VALUE_1";
    MyEnum[MyEnum["VALUE_3"] = 1] = "VALUE_3";
    MyEnum[MyEnum["VALUE_2"] = 2] = "VALUE_2";
})(MyEnum || (MyEnum = {}));
Run Code Online (Sandbox Code Playgroud)

您会看到每个都根据位置获得一个序数,因此第一个为 0,最后一个为 2。

如果你引用一个枚举,你只会得到一个数字:

console.log(MyEnum.VALUE_3); // 1
Run Code Online (Sandbox Code Playgroud)

如果要对列表进行排序:

let list = [MyEnum.VALUE_3, MyEnum.VALUE_1, MyEnum.VALUE_2];
console.log(list); // [1, 0, 2]
list.sort((a, b) => a - b);
console.log(list); // [0, 1, 2]
Run Code Online (Sandbox Code Playgroud)

如果您想要按序数排序的枚举的字符串名称列表,那么您可以执行以下操作:

let names = list.map(ordinal => MyEnum[ordinal]);
console.log(names); // ["VALUE_1", "VALUE_3", "VALUE_2"]
Run Code Online (Sandbox Code Playgroud)

操场上的代码


编辑

你可以用同样的方式排序,不管你如何设置枚举值,你只需要改变比较函数
例如,这将根据枚举字符串值的字典顺序对列表进行排序:

enum MyEnum {
    VALUE_1 = "value 1" as any,
    VALUE_3 = "value 3" as any,
    VALUE_2 = "value 2" as any
}

let list = [MyEnum.VALUE_3, MyEnum.VALUE_1, MyEnum.VALUE_2];
console.log(list); // ["value 3", "value 1", "value 2"]
list.sort((a, b) => {
    if (a < b) return -1;
    if (a > b) return 1;
    return 0;
});
console.log(list); // ["value 1", "value 2", "value 3"]

let names = list.map(ordinal => MyEnum[ordinal]);
console.log(names); // ["VALUE_1", "VALUE_2", "VALUE_3"]
Run Code Online (Sandbox Code Playgroud)

操场上的代码


编辑 #2

按枚举的原始顺序排序很棘手,您可以尝试:

enum MyEnum {
    VALUE_1 = "value 1" as any,
    VALUE_3 = "value 3" as any,
    VALUE_2 = "value 2" as any
}

let list = [MyEnum.VALUE_3, MyEnum.VALUE_1, MyEnum.VALUE_2];
console.log(list); // ["value 3", "value 1", "value 2"]

let sorted = [] as MyEnum[];
let index = 0;
for (let key in MyEnum) {
    if (index % 2 === 0) {
        sorted.push(key as any);
    }

    index++;
}

console.log(sorted); // ["VALUE_1", "VALUE_3", "VALUE_2"]

let names = sorted.map(ordinal => MyEnum[ordinal]);
console.log(names); // ["value 1", "value 3", "value 2"]
Run Code Online (Sandbox Code Playgroud)

操场上的代码

这似乎有效,但您不应该指望在 for/in 循环中收到的顺序,除非您不关心跨浏览器行为(或特定的资源管理器支持),您可以在MDN


小智 5

这是另一个解决方案。即使代码的其他贡献者更改了枚举的顺序,这也可以防止出现缺陷。

enum Action {
    EAT = 'EAT',
    PLAY = 'PLAY',
    SING = 'SING',
    SLEEP = 'SLEEP',
}

const actionOrder = {
    [Action.SING] : 1,
    [Action.PLAY] : 2,
    [Action.EAT] : 3,
    [Action.SLEEP] : 4,  
} as const;

const users = [{
    "name": "Mike",
    "action": Action.EAT
}, {
    "name": "John",
    "action": Action.SLEEP
}, {
    "name": "Harry",
    "action": Action.PLAY
}
];

users.sort((a,b) => {
    return actionOrder[a.action] - actionOrder[b.action];
});

console.log(users);
Run Code Online (Sandbox Code Playgroud)