Skip to content

Commit

Permalink
feat: add makeNumberCompareFn
Browse files Browse the repository at this point in the history
  • Loading branch information
spawnia committed Jun 24, 2024
1 parent 0ff09eb commit 262db91
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 1 deletion.
28 changes: 28 additions & 0 deletions src/array.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
sortByArray,
toggleElement,
withoutIndex,
makeNumberCompareFn,
} from './array';
import { Maybe } from './types';

Expand Down Expand Up @@ -229,6 +230,33 @@ describe('makeStringCompareFn', () => {
});
});

describe('makeNumberCompareFn', () => {
it('creates a compare function that sorts numbers', () => {
type MaybeKeyNumber = { key?: Maybe<number> };
const compareFn = makeNumberCompareFn<MaybeKeyNumber>(
(record) => record.key,
);
const original: Array<MaybeKeyNumber> = [
{ key: 3 },
{ key: 0 },
{ key: undefined },
{ key: 1 },
{ key: null },
{ key: 2 },
{},
];
expect(original.sort(compareFn)).toEqual([
{ key: 0 },
{ key: undefined },
{ key: null },
{},
{ key: 1 },
{ key: 2 },
{ key: 3 },
]);
});
});

describe('localeCompareStrings', () => {
it('sorts strings', () => {
const original: Array<string> = ['c', '', 'a', 'b'];
Expand Down
19 changes: 18 additions & 1 deletion src/array.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ export function sortByArray<T extends string | number>(
}

/**
* Takes a function that maps the values to sort and returns a compare function
* Takes a function that maps the values to sort to strings and returns a compare function
* using `String.prototype.localeCompare`, usable in `Array.toSorted` or similar APIs.
*
* null, undefined and the empty string are not distinguished and first in sort order.
Expand All @@ -109,6 +109,23 @@ export function makeStringCompareFn<TSortable>(
};
}

/**
* Takes a function that maps the values to sort to numbers and returns a compare function
* using subtraction, usable in `Array.toSorted` or similar APIs.
*
* null, undefined and 0 are not distinguished and first in sort order.
*/
export function makeNumberCompareFn<TSortable>(
map: (sortable: TSortable) => Maybe<number>,
): (a: TSortable, b: TSortable) => number {
return (a, b) => {
const mappedA = map(a) ?? 0;
const mappedB = map(b) ?? 0;

return mappedA - mappedB;
};
}

/**
* Returns a compare function for values that are string, null or undefined,
* using `String.prototype.localeCompare`, usable in `Array.toSorted` or similar APIs.
Expand Down

0 comments on commit 262db91

Please sign in to comment.