Is it possible to have a list of enums sorted by the order these enums were declared?
enum MyEnum {
VALUE_1,
VALUE_3,
VALUE_2
}
I create a list in a random order
let list = [MyEnum.VALUE_3, MyEnum.VALUE_1, MyEnum.VALUE_2];
But it gets ordered as the enum was declared
[MyEnum.VALUE_1, MyEnum.VALUE_3, MyEnum.VALUE_2]
PS: I really want to know if typescript orders the list out of the box as we have in Java, without having to order it by my own. If I had to order the list by my own I would be prone to errors if the order ever gets changed.
TypeScript defines the numeric value of an enum's member based on the order of that member that appears in the enum definition. For example, Jan takes 0, Feb gets 1, etc. In this example, the Jan constant value takes 1 instead of 0. The Feb takes 2, and the Mar takes 3, etc.
We can use the natural sort order or sort by their properties. Any Enum type we create implements the Comparable interface. Below is an excerpt from the Java documentation. Enum<E> implements Comparable<E> via the natural order of the enum (the order in which the values are declared).
An enum type is a special data type that enables for a variable to be a set of predefined constants. The variable must be equal to one of the values that have been predefined for it.
You can always use a type assertion: // typescript enum example enum foo { ONE = 1, TWO = 2, THREE = 3 } (foo as any).
Had the same problem just now. This is my solution:
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))
If you look at the compiled javascript of your enum:
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 = {}));
You'll see that each gets an ordinal number based on the position, so the first is 0 and the last is 2.
If you refer to an enum you'll just get a number back:
console.log(MyEnum.VALUE_3); // 1
If you want to sort your list:
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]
If you want the list of the string names of the enum sorted by the ordinal then you can do:
let names = list.map(ordinal => MyEnum[ordinal]);
console.log(names); // ["VALUE_1", "VALUE_3", "VALUE_2"]
(code in playground)
You can sort in the same way, regardless of how you set the enum values, you just need to change the compare function.
For example, this will sort the list based on the lexicographical order of the enum string values:
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"]
(code in playground)
Sorting by the original order of the enum is tricky, you can try:
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"]
(code in playground)
This seems to work, but you shouldn't count on the order which is received in the for/in loop, unless you don't care about cross-browser behavior (or to be specific explorer support), you can read about it in MDN.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With