Last active
August 6, 2025 12:23
-
-
Save erkobridee/a7bcbc6c50044f9178c002f8eb2766aa to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
dynamic sorting an object array | |
https://dev.to/fpaghar/donesort-an-array-of-objects-ways-in-javascript-48hl | |
*/ | |
const SortDirection = { | |
Asc: 1, | |
Desc: -1 | |
} as const; | |
type TSortDirectionKeys = keyof typeof SortDirection; | |
type TSortDirection = typeof SortDirection[TSortDirectionKeys]; | |
type DynamicSortByFn<T, R = number | string> = (item: T) => R; | |
interface DynamicSortOption<T> { | |
by: DynamicSortByFn<T>; | |
direction?: TSortDirection; | |
isAlphabetical?: boolean; | |
}; | |
const dynamicSort = <T = unknown>(collection: T[], sortOptions: DynamicSortOption<T>[]): T[] => { | |
const sortOptionsLength = sortOptions.length | |
return sortOptionsLength === 0 ? [...collection] : ( | |
collection.toSorted((itemA, itemB) => { | |
for (let sortIndex = 0; sortIndex < sortOptionsLength; sortIndex++) { | |
const { by, direction = SortDirection.Asc, isAlphabetical = false } = sortOptions[sortIndex]; | |
const a = direction === SortDirection.Asc ? by(itemA) : by(itemB); | |
const b = direction === SortDirection.Asc ? by(itemB) : by(itemA); | |
let diff = 0; | |
switch (typeof a) { | |
case 'number': | |
diff = (a as number) - (b as number); | |
break; | |
case 'string': | |
const aString = a as string; | |
const bString = b as string; | |
diff = ( | |
isAlphabetical ? | |
aString.localeCompare(bString) : | |
aString === bString ? | |
0 : | |
aString > bString ? 1 : -1 | |
); | |
break; | |
} | |
if ( diff !== 0 ) { | |
return diff; | |
} | |
} | |
return 0; | |
}) | |
); | |
} | |
//---------------------------------------------------------------------// | |
// @begin: mocked data | |
const collection = [ | |
{ code: '1-1:4.55.0', startDate: '2022-01-01', endDate: null }, | |
{ code: '1-1:3.55.0', startDate: '2022-01-01', endDate: null }, | |
{ code: '1-1:2.55.0', startDate: '2023-01-01', endDate: '2024-01-01' }, | |
{ code: '1-1:1.55.0', startDate: '2023-01-01', endDate: '2024-01-01' }, | |
]; | |
// @end: mocked data | |
//---------------------------------------------------------------------// | |
const today = new Date() | |
const result = dynamicSort(collection, [ | |
{ by: ( item ) => (item.endDate === null ? today : new Date(item.endDate)).getTime(), direction: SortDirection.Desc }, | |
{ by: ( item ) => (item.startDate === null ? today : new Date(item.startDate)).getTime(), direction: SortDirection.Desc }, | |
{ by: ( item ) => item.code, isAlphabetical: true }, | |
]); | |
console.log( result ); | |
/* output: | |
[{ | |
"code": "1-1:3.55.0", | |
"startDate": "2022-01-01", | |
"endDate": null | |
}, { | |
"code": "1-1:4.55.0", | |
"startDate": "2022-01-01", | |
"endDate": null | |
}, { | |
"code": "1-1:1.55.0", | |
"startDate": "2023-01-01", | |
"endDate": "2024-01-01" | |
}, { | |
"code": "1-1:2.55.0", | |
"startDate": "2023-01-01", | |
"endDate": "2024-01-01" | |
}] | |
*/ | |
// TypeScript Playground | |
// https://www.typescriptlang.org/play/?target=99&moduleResolution=99&module=200&ts=5.9.2#code/MYewdgzgLgBAyiATlAIgS0QU2FN4YC8MA3gFAwUwCCEwAXDAIwA05lKmtDAtI6QL4wAhhBihIUANylSUAJ4AHTDAAqCZOiw48YANKY5oogGsDIAGYx5Si-CSoM2XOGnXla+5qc7CVxZlt1By1nMABtDw1HbXB9QwBdaVl-GBQ5MCEAWzRgIIAhOQAxMAAeFWYYACVfMABXTIAjTEQYAB8YaEQ0MABzAD5fAAo0KExMhhUASkIByqTu0cRzIWBlNIzs3PsAeQVQsoGyCga5BnWsnPyi0pU+6QoAE2jQgH4JoK8YsHuYNAgqAA2CgAFkImrhgEIAW8YA0QCAAZghN8BElxNAYA90hctshfGVfLUwMYwCAAO5gPqDUAAxFfCZheIVCA7PY6CBnbGbIK7fa3RmTBnxGYkNjo2As5C89kAGUwvSgwN8kqg0vAEAAdIiFcCZBQsFBaogwB1WaEIHKdYQCEQAAwwF4wMIal00umhYUMQZsChu7zgDVQEBBTAPQbDUaZKgVEZjPLTAiHH2UcxIGCDRES+wASTAD0wAA9fLbJKbkLn80WSmXVWz1ZaeorSyqK4WANRt6ZHSg98UkWFyCpPEI+IgfZ46DU0YAx-5A0HgnJQ3zLAEQZSCIgqtWQMItvOFxJ6nuUPtCXzD-0mm1jzwTgPTh0DiNjKjTBgnF+ZeM-E9idWwA0F73teNp2FEI4PrQT6frG37vs+cFvkkf4UJmmJoOYlh2ihqEQGSIzAEqgxuLYQhdsmf6QuuMAAOR1I0zS0XQlGoU8WFDOeIgwAxTSINM3DpkB3G8c0ky-qhxxYEIxgSVRIjKLRnTdD0zGsVRAHCHAUBdL0vhcaIym9HJqF9g02m6T0vjCYZOkqbhkmPJh2HpupqF-ICIJgpgELLi8bmSUIFkqVqICQoiADCICZAoQhYIM5l2b074BahQVJVZN6wsFen+Y5jn2ix+WBTlVkDIlllPowMA8HwxUwOJqVSUislufwx5-ph6YYRxACEYH2hR+UGkaJrseYJkUO1f7taxI3GjAJbJvwkxsI1s0APQbdwO27Xt+0HYdR3HSdp27VtpBbTAAACTQ9N0DCZGFpgPJiQhQEIMh9n6Xy+GEbDEP++YMLRjC8HQAAsGoAKzQxqtq0cyH0aO9mAgwATLa6Po9wtpg3jiMwPKDwoKjDB1LSMD8KwFCA6AwN0WDjB0AAzDDcMI0jcWoGTdGY9juP44whPE6Tozk7UlPUwDQNo4z4Po+z8OE9A3Ni3LtH8yzguCyLebqxjWMQzrBNUzT-b0xrTN0IwSucx0yM8+LfNY9reO6xUou85rRsm8LZukEel0bTdxOPc9oZvR9wdnbHcfx-HF2kH2QYPEIcg1JgZKpKjgyrX2WAQJLsBEFiGyXPY1IIu6OgVP9tMDl6vyRg1IpfhqXujNaRAUwCT6p+nNU8VnOejO3neYJMkwaj0PkqGgmSYHnQ4gQw46QWAGocNB0sNycTdwa3ibpnBGqqyjXdZb3-cgGnGfkyP6vt+fTuT9Ps9QPPi-LxhG9r3eG8t6cGAAHPepxuqHwTAMU+ltZyeQXD5JcAIGA6VqBuVg8RGrJ3VAiTAoUeiDBgIXYuDVJBAA |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment