multiKeyComparatorWithNullsLast
JavaScript
// Builds a comparator for records with ordered keys and nullish values last.
const isNullish = (value) => value === null || value === undefined;
export function multiKeyComparator(keys, collator = new Intl.Collator()) {
return (left, right) => {
for (const spec of keys) {
const key = typeof spec === 'string' ? spec : spec.key;
const direction = typeof spec === 'string' || spec.direction !== 'desc' ? 1 : -1;
const a = left?.[key];
const b = right?.[key];
if (isNullish(a) && isNullish(b)) continue;
if (isNullish(a)) return 1; // nullish always sorts last, even descending
if (isNullish(b)) return -1;
let result = 0;
if (typeof a === 'number' && typeof b === 'number') result = a - b;
else if (a instanceof Date && b instanceof Date) result = a.getTime() - b.getTime();
else result = collator.compare(String(a), String(b));
if (result !== 0) return result * direction;
}
return 0;
};
}