Last active
October 28, 2025 15:27
-
-
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
| /** | |
| * A getter that produces the value to compare for a given item. | |
| * | |
| * @template T | |
| * @callback order__Getter | |
| * @param {T} item The current item from the array. | |
| * @param {number} index The index of the current item. | |
| * @param {T[]} array The entire array being ordered. | |
| * @param {number} criterionIndex The index of the current criterion. | |
| * @returns {number|string|bigint|boolean|Date} A value that can be ordered with < and >. | |
| */ | |
| /** | |
| * An object form of a sorting criterion. | |
| * | |
| * @template T | |
| * @typedef {Object} order__CriterionObject | |
| * @property {order__Getter<T>} getter Function producing a comparable value for an item. | |
| * @property {boolean} [reverse=false] Sort descending if true (ascending by default). | |
| */ | |
| /** | |
| * Order an array by one or more criteria. Each criterion can be a getter function or | |
| * an object containing `{ getter, reverse }`. When a plain function is supplied, it is | |
| * treated as `{ getter: fn, reverse: false }` (ascending). | |
| * | |
| * @template T | |
| * @param {T[]} array The array to order. | |
| * @param {...(order__Getter<T> | order__CriterionObject<T>)} criterion One or more criteria to apply, in precedence order. | |
| * @returns {T[]} A new array ordered by the provided criteria. | |
| */ | |
| function order(array, ...criterion) { | |
| const criterionCount = criterion.length; | |
| return array.map((item, index) => ({ | |
| item, | |
| criterion: criterion.map((criteria, cIndex) => { | |
| criteria = typeof criteria === 'function' ? {getter: criteria, reverse: false} : criteria; | |
| return { | |
| value: criteria.getter(item, index, array, cIndex), | |
| reverse: !!criteria.reverse | |
| }; | |
| }) | |
| })) | |
| .sort((a, b) => { | |
| for (let i = 0; i < criterionCount; i++) { | |
| const {value: aCritValue, reverse} = a.criterion[i]; | |
| const bCritValue = b.criterion[i].value; | |
| if (aCritValue < bCritValue) { | |
| return reverse ? 1 : -1; | |
| } | |
| else if (aCritValue > bCritValue) { | |
| return reverse ? -1 : 1; | |
| } | |
| } | |
| return 0; | |
| }) | |
| .map(x => x.item); | |
| } |
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
| console.log( | |
| order( | |
| [ | |
| {firstName: 'Chris', lastName: 'West'}, | |
| {firstName: 'Chris', lastName: 'Brown'}, | |
| {firstName: 'Chris', lastName: 'Hemsworth'}, | |
| {firstName: 'Kim', lastName: 'Kardashian'}, | |
| {firstName: 'Gregorio', lastName: 'Arancibia'}, | |
| ], | |
| entry => entry.firstName, | |
| {getter: entry => entry.lastName, reverse: true}, | |
| ) | |
| ); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment