-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathindex.ts
53 lines (48 loc) · 1.46 KB
/
index.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
export type Direction = 'ASC' | 'DESC'
export type SortArray<T> = [keyof T, Direction][]
export type SortObject<T> = { [key in keyof T]?: Direction }
export type GetColumnValue<T> = (column: keyof T, value: T[keyof T]) => any
const sort = <T>(
a: T,
b: T,
columns: SortArray<T>,
getColumnValue?: GetColumnValue<T>
): -1 | 0 | 1 => {
const [item, ...others] = columns
const [column, orderBy] = item
const valueA = getColumnValue ? getColumnValue(column, a[column]) : a[column]
const valueB = getColumnValue ? getColumnValue(column, b[column]) : b[column]
if (orderBy === 'ASC') {
if (valueA > valueB) return 1
if (valueA < valueB) return -1
if (others.length) return sort(a, b, others, getColumnValue)
return 0
} else {
if (valueB > valueA) return 1
if (valueB < valueA) return -1
if (others.length) return sort(a, b, others, getColumnValue)
return 0
}
}
const sortObjectToArray = <T>(object: SortObject<T>): SortArray<T> =>
Object.keys(object).reduce(
(arr, column) =>
[...arr, [column, object[column as keyof T]]] as SortArray<T>,
[] as SortArray<T>
)
const multiColumnSort = <T>(
arr: T[],
sortArrOrObject: SortArray<T> | SortObject<T>,
getColumnValue?: GetColumnValue<T>
): T[] =>
[...arr].sort((a, b) =>
sort(
a,
b,
Array.isArray(sortArrOrObject)
? sortArrOrObject
: sortObjectToArray(sortArrOrObject),
getColumnValue
)
)
export default multiColumnSort