compareBy
The compareBy utility is a factory function that creates a comparator based on a selector function. It is ideal for sorting arrays of objects by a specific property or a computed value.
Implementation
View Source Code
ts
import { compare } from './compare';
/**
* Compares two objects based on multiple selectors.
* The comparison is done in the order of the selectors provided.
* Each selector can be 'asc' for ascending or 'desc' for descending order.
*
* @example
* ```ts
* const compareByNameAndAge = compareBy<{ name: string; age: number }>({
* name: 'asc',
* age: 'desc',
* });
*
* const a = { name: 'Alice', age: 30 };
* const b = { name: 'Bob', age: 25 };
*
* console.log(compareByNameAndAge(a, b)); // -1 (Alice < Bob)
* ```
*
* @param selectors - An object where keys are properties to compare and values are 'asc' or 'desc'.
*
* @returns A comparison function that can be used with array sorting methods.
*/
export const compareBy = <T>(selectors: Partial<Record<keyof T, 'asc' | 'desc'>>) => {
const entries = Object.entries(selectors) as [keyof T, 'asc' | 'desc'][];
return (a: T, b: T) => {
for (const [key, direction] of entries) {
const v1 = a[key];
const v2 = b[key];
const dir = direction === 'desc' ? -1 : 1;
const cmp = compare(v1, v2);
if (cmp !== 0) return cmp * dir;
}
return 0;
};
};Features
- Isomorphic: Works in both Browser and Node.js.
- Integrated Comparison: Uses the
compareutility internally for reliable ordering. - Standard Interface: Returns a comparator compatible with native
Array.prototype.sort(). - Type-safe: Properly typed for objects and their selected properties.
API
ts
function compareBy<T>(selector: (item: T) => any): (a: T, b: T) => -1 | 0 | 1;Parameters
selector: A function that receives an item and returns the value to be used for comparison.
Returns
- A comparator function that takes two items (
a,b) and returns-1,0, or1.
Examples
Sorting Objects by Property
ts
import { compareBy } from '@vielzeug/toolkit';
const users = [
{ name: 'Charlie', age: 35 },
{ name: 'Alice', age: 30 },
{ name: 'Bob', age: 25 },
];
// Create a comparator for the 'age' property
const byAge = compareBy((u) => u.age);
users.sort(byAge);
// Results in: Bob (25), Alice (30), Charlie (35)Sorting with Computed Values
ts
import { compareBy } from '@vielzeug/toolkit';
const files = ['data.json', 'report.pdf', 'README.md'];
// Sort by extension length
const byExtLength = compareBy((f) => f.split('.').pop()?.length || 0);
files.sort(byExtLength);Implementation Notes
- Performance-optimized factory that pre-binds the selector.
- Internally leverages
compareto handle the logic for primitives. - Throws
TypeErrorifselectoris not a function.