Last active
June 18, 2025 19:36
-
-
Save westc/0fa192d75838f9323046c9b39ec79f2f to your computer and use it in GitHub Desktop.
order() - Sorts an array based on one or more criteria.
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
/** | |
* Sorts an array based on one or more criteria. | |
* | |
* @template T | |
* @param {T[]} array - The array to sort. | |
* @param {...(((item: T, index: number) => any) | ({getter: (item: T, index: number) => any, reverse: boolean}))} criterion - | |
* One or more sorting criteria. Each can be a getter function or an object with a getter and a reverse flag. | |
* @returns {T[]} A new array sorted based on the provided criteria. | |
*/ | |
function order(array, ...criterion) { | |
const criterionCount = criterion.length; | |
criterion = criterion.map(c => 'function' === typeof c ? {getter: c, reverse: false} : c); | |
return array.map(item => ({item, criterion: []})) | |
.sort((a, b) => { | |
const criterionA = a.criterion; | |
const criterionB = b.criterion; | |
for (let i = 0; i < criterionCount; i++) { | |
// Get the values to be compared. | |
if (criterionA.length === i) { | |
criterionA.push(criterion[i].getter(a.item, i)); | |
} | |
const criteriaA = criterionA[i]; | |
if (criterionB.length === i) { | |
criterionB.push(criterion[i].getter(b.item, i)); | |
} | |
const criteriaB = criterionB[i]; | |
// If less than or greater than then short-circuit and return a value | |
// from this sort() callback. | |
const isLesser = criteriaA < criteriaB; | |
if (isLesser || criteriaA > criteriaB) { | |
return (criterion[i].reverse ? -1 : 1) * (isLesser ? -1 : 1); | |
} | |
} | |
return 0; | |
}) | |
.map(x => x.item); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment