sorters
v1.1.0
Published
Sort function generators
Downloads
71
Readme
Sorters is a compact package for generating Javascript array sort
comparators that handle things like null values, descending sort, and multi-level comparisons.
Usage
The sorter
function builds and returns a comparator function that uses the specified comparison order. This returned function can be used with Array.sort
or just to order any two objects.
import { sorter } from 'sorters';
let data = [
{ a: 5, b: 'strb', c: new Date('2017-06-01') },
{ a: 2, b: 'stra', c: new Date('2018-05-01') },
{ a: null, b: null },
{ a: 2, b: 'strc', c: new Date('2018-02-01') },
];
// Sort first on `c`, counting nullish values as higher than the others.
// If `c` is equal on two objects, use `a` in ascending order, and if `a` is equal then sort by
// `b` in descending order.
data.sort(sorter(
{ value: 'c', nulls: Nulls.High },
'a',
{ value: (val) => val.b, descending: true, type: ValueType.String }
));
// Result:
[
{ a: 5, b: 'strb', c: 2017-06-01T00:00:00.000Z },
{ a: 2, b: 'strc', c: 2018-02-01T00:00:00.000Z },
{ a: 2, b: 'stra', c: 2018-05-01T00:00:00.000Z },
{ a: null, b: null }
]
Examples
Sort by the value of the a
field in ascending order.
> data.sort(sorter('a'))
[
{ a: null, b: null },
{ a: 2, b: 'strc', c: 2018-02-01T00:00:00.000Z },
{ a: 2, b: 'stra', c: 2018-05-01T00:00:00.000Z },
{ a: 5, b: 'strb', c: 2017-06-01T00:00:00.000Z }
]
Sort by the value of the a
field in descending order.
> data.sort(sorter({ value: 'a', descending: true }));
[
{ a: 5, b: 'strb', c: 2017-06-01T00:00:00.000Z },
{ a: 2, b: 'strc', c: 2018-02-01T00:00:00.000Z },
{ a: 2, b: 'stra', c: 2018-05-01T00:00:00.000Z },
{ a: null, b: null }
]
Sort by the month value of the c
field.
// Note the `?.` operator to handle when `c` is missing.
> data.sort(sorter((obj) => obj.c?.getUTCMonth()));
[
{ a: null, b: null },
{ a: 2, b: 'strc', c: 2018-02-01T00:00:00.000Z },
{ a: 2, b: 'stra', c: 2018-05-01T00:00:00.000Z },
{ a: 5, b: 'strb', c: 2017-06-01T00:00:00.000Z }
]
Sort by the a
field, and when comparing objects with the same value for a
, compare b
instead.
> data.sort(sorter('a', 'b'));
[
{ a: null, b: null },
{ a: 2, b: 'stra', c: 2018-05-01T00:00:00.000Z },
{ a: 2, b: 'strc', c: 2018-02-01T00:00:00.000Z },
{ a: 5, b: 'strb', c: 2017-06-01T00:00:00.000Z }
]
Same, but when comparing b
use descending order.
> data.sort(sorter('a', { value: 'b', descending: true }));
[
{ a: null, b: null },
{ a: 2, b: 'strc', c: 2018-02-01T00:00:00.000Z },
{ a: 2, b: 'stra', c: 2018-05-01T00:00:00.000Z },
{ a: 5, b: 'strb', c: 2017-06-01T00:00:00.000Z }
]
Sort by a
ascending, and counting nullish values as higher than the others.
> data.sort(sorter({ value: 'a', nulls: Nulls.High /* or just 'high` if not using Typescript */))
[
{ a: 2, b: 'strc', c: 2018-02-01T00:00:00.000Z },
{ a: 2, b: 'stra', c: 2018-05-01T00:00:00.000Z },
{ a: 5, b: 'strb', c: 2017-06-01T00:00:00.000Z },
{ a: null, b: null }
]
Arguments
Each argument to the sorter
function is an object that represents how to perform a single level of the sort.
If two items in the array are equal for a particular level, then the next level is tried, and so on until a difference is found or all levels have equal values.
The object contains four properties:
value
value
specifies which field to access in each item. It can be a function, a string specifying a path, or an array specifying a path.
When value
is the only argument required, it can also be passed directly as the argument instead of wrapping it with an object, as in the 'a'
argument in the example above.
descending
descending
is an optional boolean indicating that the sort should be done in descending order. If omitted, the sort is done in ascending order.
type
type
gives the sorter a hint as the to type of data it will encounter. Typescript users can use the ValueType
enum, and others can use the values string
, number
, and date
.
If some of the data does not match the specified type, you will likely encounter incorrect results or an error.
The default value is any
, which will detect the type of value as it is sorted and act appropriately.
export enum ValueType {
Any = 'any',
String = 'string',
Number = 'number',
Date = 'date',
}
nulls
How to treat null or undefined values in the data. Typescript users can use the Nulls
enum, while others can use the values low
, high
, and none
.
export enum Nulls {
/** Treat nulls as lower than any other values. This is the default setting. */
Low = 'low',
/** Treat nulls as higher than any other values. */
High = 'high',
/** Assume there are no nullish values in the data. This may cause exceptions if you are wrong. */
None = 'none',
}
Using Nulls.None
in data that contains nullish values will probably cause an error.