Skip to content

Instantly share code, notes, and snippets.

@westc
Last active June 18, 2025 19:36
Show Gist options
  • Save westc/0fa192d75838f9323046c9b39ec79f2f to your computer and use it in GitHub Desktop.
Save westc/0fa192d75838f9323046c9b39ec79f2f to your computer and use it in GitHub Desktop.
order() - Sorts an array based on one or more criteria.
/**
* 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