-
Notifications
You must be signed in to change notification settings - Fork 1
/
sort.ts
54 lines (51 loc) · 1.99 KB
/
sort.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
54
/*
* Copyright 2019 LABOR.digital
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Last modified: 2019.02.01 at 18:58
*/
import type {List, ListPath, ReadList} from '../Interfaces/List';
import {isNull} from '../Types/isNull';
import {isUndefined} from '../Types/isUndefined';
import {forEach} from './forEach';
import {getListType, getNewList, setListValue} from './listAccess';
import {getPath} from './Paths/getPath';
/**
* Can be used to sort arrays containing objects by a property of said objects
* Can also be used to sort plain objects, containing other objects in the same way
*
* @param list the list to sort
* @param by The property of the child objects to sort by
* @param desc If set to true the result will be sorted descending instead of the default which is ascending
*/
export function sort<V, K>(list: ReadList<V, K>, by?: ListPath | null, desc?: boolean): List<V, K>
{
// Build the sorter
let sorter: Array<{ by: V | ListPath | any, k: any, v: any }> = [];
forEach(list, (v, k) => {
sorter.push({
by: isNull(by) || isUndefined(by) ? v : getPath(v, by),
k, v
});
});
// Sort the sorter array
sorter = sorter.sort((a, b) =>
desc ?
((a.by > b.by) ? -1 : ((a.by < b.by) ? 1 : 0)) :
((a.by < b.by) ? -1 : ((a.by > b.by) ? 1 : 0)));
// Build result
const result = getNewList<V, K>(getListType(list));
forEach(sorter, (o) => setListValue(result, o.v, o.k));
return result;
}