@hkdigital/lib-sveltekit 0.0.42 → 0.0.44
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/dist/classes/data/IterableTree.d.ts +51 -0
- package/dist/classes/data/IterableTree.js +243 -0
- package/dist/classes/data/Selector.d.ts +28 -0
- package/dist/classes/data/Selector.js +188 -0
- package/dist/classes/data/index.d.ts +2 -0
- package/dist/classes/data/index.js +2 -0
- package/dist/classes/index.d.ts +1 -0
- package/dist/classes/index.js +1 -0
- package/dist/index.js +1 -1
- package/dist/util/array/index.d.ts +171 -0
- package/dist/util/array/index.js +432 -0
- package/dist/util/compare/index.d.ts +68 -0
- package/dist/util/compare/index.js +247 -0
- package/dist/util/expect/index.d.ts +113 -2
- package/dist/util/expect/index.js +215 -28
- package/dist/util/is/index.d.ts +67 -0
- package/dist/util/is/index.js +154 -0
- package/dist/util/iterate/index.d.ts +131 -0
- package/dist/util/iterate/index.js +234 -0
- package/dist/util/object/index.d.ts +326 -0
- package/dist/util/object/index.js +1361 -0
- package/dist/util/string/index.d.ts +60 -0
- package/dist/util/string/index.js +184 -0
- package/package.json +1 -1
@@ -0,0 +1,67 @@
|
|
1
|
+
/**
|
2
|
+
* Check if a value looks like an array
|
3
|
+
*
|
4
|
+
* @param {mixed} item - Item to check
|
5
|
+
*
|
6
|
+
* @return {boolean} true if the value looks like an array
|
7
|
+
*/
|
8
|
+
export function isArrayLike(item: mixed): boolean;
|
9
|
+
/**
|
10
|
+
* Check if a value is an Arguments object
|
11
|
+
*
|
12
|
+
* @param {*} value
|
13
|
+
*
|
14
|
+
* @returns {boolean} true if the value is an Arguments object
|
15
|
+
*/
|
16
|
+
export function isArguments(value: any): boolean;
|
17
|
+
/**
|
18
|
+
* Check if a value is an array that only contains primitives
|
19
|
+
* - A primitive is a not-object value
|
20
|
+
*
|
21
|
+
* @param {mixed} value - value to check
|
22
|
+
*
|
23
|
+
* @return {boolean} true if the value is an array of primitives
|
24
|
+
*/
|
25
|
+
export function isArrayOfPrimitives(arr: any): boolean;
|
26
|
+
/**
|
27
|
+
* Check if the supplied value is async iterable
|
28
|
+
* - Aync iterable objects must implement the "@@asyncIterator" method
|
29
|
+
*
|
30
|
+
* @param {mixed} value
|
31
|
+
*
|
32
|
+
* @returns {boolean} true if the value is async iterable
|
33
|
+
*/
|
34
|
+
export function isAsyncIterator(value: mixed): boolean;
|
35
|
+
/**
|
36
|
+
* Check if the supplied value is an async function
|
37
|
+
* - Returns true for functions declared as "async function" or
|
38
|
+
* async () => {}
|
39
|
+
*
|
40
|
+
* @warning this function does not return [true] for (sync) functions that
|
41
|
+
* return a promise.
|
42
|
+
*
|
43
|
+
* @param {mixed} value
|
44
|
+
*
|
45
|
+
* @returns {boolean} true if the value is an async function
|
46
|
+
*/
|
47
|
+
export function isAsyncFunction(value: mixed): boolean;
|
48
|
+
/**
|
49
|
+
* Check if the supplied value is iterable
|
50
|
+
* - Iterable objects must implement the "@@iterator" method
|
51
|
+
* - Generators are also iterable
|
52
|
+
*
|
53
|
+
* @param {mixed} value
|
54
|
+
*
|
55
|
+
* @returns {boolean} true if the value is (not async) iterable
|
56
|
+
*/
|
57
|
+
export function isIterable(value: mixed): boolean;
|
58
|
+
/**
|
59
|
+
* Check if the supplied value is an object bu not a promise
|
60
|
+
* - Promises return false
|
61
|
+
* - Arrays return true
|
62
|
+
*
|
63
|
+
* @param {mixed} value
|
64
|
+
*
|
65
|
+
* @returns {boolean} true if the value is an Object, but not a Promise
|
66
|
+
*/
|
67
|
+
export function isObject(value: mixed): boolean;
|
@@ -0,0 +1,154 @@
|
|
1
|
+
/* ---------------------------------------------------------------- Internals */
|
2
|
+
|
3
|
+
//
|
4
|
+
// @see https://developer.mozilla.org/
|
5
|
+
// en-US/docs/Web/JavaScript/Reference/Global_Objects/AsyncFunction
|
6
|
+
//
|
7
|
+
const AsyncFunction = Object.getPrototypeOf(async () => {}).constructor;
|
8
|
+
const objectToString = Object.prototype.toString;
|
9
|
+
|
10
|
+
/* ------------------------------------------------------------------ Exports */
|
11
|
+
|
12
|
+
// ---------------------------------------------------------------------- Method
|
13
|
+
|
14
|
+
/**
|
15
|
+
* Check if a value looks like an array
|
16
|
+
*
|
17
|
+
* @param {mixed} item - Item to check
|
18
|
+
*
|
19
|
+
* @return {boolean} true if the value looks like an array
|
20
|
+
*/
|
21
|
+
export function isArrayLike(item) {
|
22
|
+
if (!(item instanceof Object)) {
|
23
|
+
return false;
|
24
|
+
}
|
25
|
+
|
26
|
+
if ('length' in item) {
|
27
|
+
return true;
|
28
|
+
}
|
29
|
+
|
30
|
+
return false;
|
31
|
+
}
|
32
|
+
|
33
|
+
// ---------------------------------------------------------------------- Method
|
34
|
+
|
35
|
+
/**
|
36
|
+
* Check if a value is an Arguments object
|
37
|
+
*
|
38
|
+
* @param {*} value
|
39
|
+
*
|
40
|
+
* @returns {boolean} true if the value is an Arguments object
|
41
|
+
*/
|
42
|
+
export function isArguments(value) {
|
43
|
+
return objectToString.call(value) === '[object Arguments]';
|
44
|
+
}
|
45
|
+
|
46
|
+
// ---------------------------------------------------------------------- Method
|
47
|
+
|
48
|
+
/**
|
49
|
+
* Check if a value is an array that only contains primitives
|
50
|
+
* - A primitive is a not-object value
|
51
|
+
*
|
52
|
+
* @param {mixed} value - value to check
|
53
|
+
*
|
54
|
+
* @return {boolean} true if the value is an array of primitives
|
55
|
+
*/
|
56
|
+
export function isArrayOfPrimitives(arr) {
|
57
|
+
if (!Array.isArray(arr)) {
|
58
|
+
return false;
|
59
|
+
}
|
60
|
+
|
61
|
+
for (let j = 0, n = arr.length; j < n; j = j + 1) {
|
62
|
+
if (arr[j] instanceof Object) {
|
63
|
+
// current value is not a primitive
|
64
|
+
return false;
|
65
|
+
}
|
66
|
+
}
|
67
|
+
|
68
|
+
return true;
|
69
|
+
}
|
70
|
+
|
71
|
+
// ---------------------------------------------------------------------- Method
|
72
|
+
|
73
|
+
/**
|
74
|
+
* Check if the supplied value is async iterable
|
75
|
+
* - Aync iterable objects must implement the "@@asyncIterator" method
|
76
|
+
*
|
77
|
+
* @param {mixed} value
|
78
|
+
*
|
79
|
+
* @returns {boolean} true if the value is async iterable
|
80
|
+
*/
|
81
|
+
export function isAsyncIterator(value) {
|
82
|
+
if (!(value instanceof Object) || typeof value[Symbol.asyncIterator] !== 'function') {
|
83
|
+
return false;
|
84
|
+
}
|
85
|
+
|
86
|
+
return true;
|
87
|
+
}
|
88
|
+
|
89
|
+
// ---------------------------------------------------------------------- Method
|
90
|
+
|
91
|
+
/**
|
92
|
+
* Check if the supplied value is an async function
|
93
|
+
* - Returns true for functions declared as "async function" or
|
94
|
+
* async () => {}
|
95
|
+
*
|
96
|
+
* @warning this function does not return [true] for (sync) functions that
|
97
|
+
* return a promise.
|
98
|
+
*
|
99
|
+
* @param {mixed} value
|
100
|
+
*
|
101
|
+
* @returns {boolean} true if the value is an async function
|
102
|
+
*/
|
103
|
+
export function isAsyncFunction(value) {
|
104
|
+
if (value instanceof AsyncFunction) {
|
105
|
+
return true;
|
106
|
+
}
|
107
|
+
|
108
|
+
return false;
|
109
|
+
}
|
110
|
+
|
111
|
+
// ---------------------------------------------------------------------- Method
|
112
|
+
|
113
|
+
/**
|
114
|
+
* Check if the supplied value is iterable
|
115
|
+
* - Iterable objects must implement the "@@iterator" method
|
116
|
+
* - Generators are also iterable
|
117
|
+
*
|
118
|
+
* @param {mixed} value
|
119
|
+
*
|
120
|
+
* @returns {boolean} true if the value is (not async) iterable
|
121
|
+
*/
|
122
|
+
export function isIterable(value) {
|
123
|
+
if (!(value instanceof Object) || typeof value[Symbol.iterator] !== 'function') {
|
124
|
+
return false;
|
125
|
+
}
|
126
|
+
|
127
|
+
return true;
|
128
|
+
}
|
129
|
+
|
130
|
+
// ---------------------------------------------------------------------- Method
|
131
|
+
|
132
|
+
/**
|
133
|
+
* Check if the supplied value is an object bu not a promise
|
134
|
+
* - Promises return false
|
135
|
+
* - Arrays return true
|
136
|
+
*
|
137
|
+
* @param {mixed} value
|
138
|
+
*
|
139
|
+
* @returns {boolean} true if the value is an Object, but not a Promise
|
140
|
+
*/
|
141
|
+
export function isObject(value) {
|
142
|
+
if (!(value instanceof Object)) {
|
143
|
+
if (value && typeof value === 'object') {
|
144
|
+
// e.g. obj = Object.create(null);
|
145
|
+
return true;
|
146
|
+
}
|
147
|
+
|
148
|
+
return false;
|
149
|
+
} else if (value instanceof Promise) {
|
150
|
+
return false;
|
151
|
+
}
|
152
|
+
|
153
|
+
return true;
|
154
|
+
}
|
@@ -0,0 +1,131 @@
|
|
1
|
+
/**
|
2
|
+
* Filter all iterated elements
|
3
|
+
*
|
4
|
+
* @param {Iterable} iterable
|
5
|
+
* @param {function} filterFn
|
6
|
+
*
|
7
|
+
* @returns {Generator} generator that produces items that pass the filter
|
8
|
+
*/
|
9
|
+
export function filter(iterable: Iterable<any>, filterFn: Function): Generator;
|
10
|
+
/**
|
11
|
+
* Map all iterated items
|
12
|
+
* - Outputs transformed items
|
13
|
+
*
|
14
|
+
* @param {Iterable} iterable
|
15
|
+
* @param {function} transformFn
|
16
|
+
*
|
17
|
+
* @returns {Generator} generator that produces transformed items
|
18
|
+
*/
|
19
|
+
export function map(iterable: Iterable<any>, transformFn: Function): Generator;
|
20
|
+
/**
|
21
|
+
* Get an Iterator object that can be used to iterate over all
|
22
|
+
* [ path, value ] entries in the object
|
23
|
+
*
|
24
|
+
* @param {Object} obj - Object to iterate
|
25
|
+
*
|
26
|
+
* @param {Object} [options] - Iteration options
|
27
|
+
*
|
28
|
+
* @param {boolean} [options.walkArrays=false]
|
29
|
+
* If set to true, the iterator will also iterate through Array objects
|
30
|
+
*
|
31
|
+
* @param {object} [options.expandPathKeys=false]
|
32
|
+
* If true, keys in the root object like "some.path.to" will be interpreted
|
33
|
+
* as paths in the object
|
34
|
+
*
|
35
|
+
* @param {object} [options.outputIntermediateNodes=false]
|
36
|
+
* If true, intermediate object nodes (not leaves) will be outputted too
|
37
|
+
*
|
38
|
+
* @param {object} [options.ignoreEmptyObjectLeaves=false]
|
39
|
+
* If true, no output will be generated for empty objects at the leaves of
|
40
|
+
* the object tree
|
41
|
+
*
|
42
|
+
* @return {Iterator} iterator object
|
43
|
+
*/
|
44
|
+
export function iterateObjectEntries(obj: any, options?: {
|
45
|
+
walkArrays?: boolean;
|
46
|
+
expandPathKeys?: object;
|
47
|
+
outputIntermediateNodes?: object;
|
48
|
+
ignoreEmptyObjectLeaves?: object;
|
49
|
+
}): Iterator<any, any, any>;
|
50
|
+
/**
|
51
|
+
* Get an Iterator object that can be used to iterate over all paths in
|
52
|
+
* the object
|
53
|
+
*
|
54
|
+
* @param {Object} obj - Object to iterate
|
55
|
+
*
|
56
|
+
* @param {Object} [options] - Iteration options
|
57
|
+
*
|
58
|
+
* @param {boolean} [options.walkArrays=false]
|
59
|
+
* If set to true, the iterator will also iterate through Array objects
|
60
|
+
*
|
61
|
+
* @param {object} [options.expandPathKeys=false]
|
62
|
+
* If true, keys in the root object like "some.path.to" will be interpreted
|
63
|
+
* as paths in the object
|
64
|
+
*
|
65
|
+
* @param {object} [options.outputIntermediateNodes=false]
|
66
|
+
* If true, intermediate object nodes (not leaves) will be outputted too
|
67
|
+
*
|
68
|
+
* @param {object} [options.ignoreEmptyObjectLeaves=false]
|
69
|
+
* If true, no output will be generated for empty objects at the leaves of
|
70
|
+
* the object tree
|
71
|
+
*
|
72
|
+
* @return {Iterator} iterator object
|
73
|
+
*/
|
74
|
+
export function iterateObjectPaths(obj: any, options?: {
|
75
|
+
walkArrays?: boolean;
|
76
|
+
expandPathKeys?: object;
|
77
|
+
outputIntermediateNodes?: object;
|
78
|
+
ignoreEmptyObjectLeaves?: object;
|
79
|
+
}): Iterator<any, any, any>;
|
80
|
+
/**
|
81
|
+
* Get an Iterator object that can be used to iterate over all values in
|
82
|
+
* the object (at the leaves of the object tree)
|
83
|
+
*
|
84
|
+
* @param {Object} obj - Object to iterate
|
85
|
+
*
|
86
|
+
* @param {Object} [options] - Iteration options
|
87
|
+
*
|
88
|
+
* @param {boolean} [options.walkArrays=false]
|
89
|
+
* If set to true, the iterator will also iterate through Array objects
|
90
|
+
*
|
91
|
+
* @param {object} [options.expandPathKeys=false]
|
92
|
+
* If true, keys in the root object like "some.path.to" will be interpreted
|
93
|
+
* as paths in the object
|
94
|
+
*
|
95
|
+
* @param {object} [options.outputIntermediateNodes=false]
|
96
|
+
* If true, intermediate object nodes (not leaves) will be outputted too
|
97
|
+
*
|
98
|
+
* @param {object} [options.ignoreEmptyObjectLeaves=false]
|
99
|
+
* If true, no output will be generated for empty objects at the leaves of
|
100
|
+
* the object tree
|
101
|
+
*
|
102
|
+
* @return {Iterator} iterator object
|
103
|
+
*/
|
104
|
+
export function iterateObjectValues(obj: any, options?: {
|
105
|
+
walkArrays?: boolean;
|
106
|
+
expandPathKeys?: object;
|
107
|
+
outputIntermediateNodes?: object;
|
108
|
+
ignoreEmptyObjectLeaves?: object;
|
109
|
+
}): Iterator<any, any, any>;
|
110
|
+
/**
|
111
|
+
* Get a list of objects returned by an iterator in sorted order
|
112
|
+
*
|
113
|
+
* --
|
114
|
+
*
|
115
|
+
* @note Sorting requires that all values are evaluated, so all items must be
|
116
|
+
* iterated
|
117
|
+
*
|
118
|
+
* --
|
119
|
+
*
|
120
|
+
* @param {Iterable} it - Iterable items
|
121
|
+
*
|
122
|
+
* @param {function} getValueFn
|
123
|
+
* Function that gets the value from the iterated objects
|
124
|
+
*
|
125
|
+
* @param {boolean} [reversed=false]
|
126
|
+
* Sort in reversed order
|
127
|
+
*
|
128
|
+
*
|
129
|
+
* @returns {array} objects outputted in sorted order
|
130
|
+
*/
|
131
|
+
export function sortObjects({ it, getValueFn, reversed }: Iterable<any>): any[];
|
@@ -0,0 +1,234 @@
|
|
1
|
+
/* ------------------------------------------------------------------ Imports */
|
2
|
+
|
3
|
+
import * as expect from '../expect/index.js';
|
4
|
+
import { smallestFirst, largestFirst } from '../compare/index.js';
|
5
|
+
|
6
|
+
import IterableTree from '../../classes/data/IterableTree.js';
|
7
|
+
|
8
|
+
/* ------------------------------------------------------------------ Exports */
|
9
|
+
|
10
|
+
/**
|
11
|
+
* Filter all iterated elements
|
12
|
+
*
|
13
|
+
* @param {Iterable} iterable
|
14
|
+
* @param {function} filterFn
|
15
|
+
*
|
16
|
+
* @returns {Generator} generator that produces items that pass the filter
|
17
|
+
*/
|
18
|
+
export function* filter(iterable, filterFn) {
|
19
|
+
expect.iterable(iterable);
|
20
|
+
expect.function(filterFn);
|
21
|
+
|
22
|
+
for (const value of iterable) {
|
23
|
+
if (filterFn(value)) {
|
24
|
+
yield value;
|
25
|
+
}
|
26
|
+
}
|
27
|
+
}
|
28
|
+
|
29
|
+
// ---------------------------------------------------------------------- Method
|
30
|
+
|
31
|
+
/**
|
32
|
+
* Map all iterated items
|
33
|
+
* - Outputs transformed items
|
34
|
+
*
|
35
|
+
* @param {Iterable} iterable
|
36
|
+
* @param {function} transformFn
|
37
|
+
*
|
38
|
+
* @returns {Generator} generator that produces transformed items
|
39
|
+
*/
|
40
|
+
export function* map(iterable, transformFn) {
|
41
|
+
expect.iterable(iterable);
|
42
|
+
expect.function(transformFn);
|
43
|
+
|
44
|
+
for (const value of iterable) {
|
45
|
+
yield transformFn(value);
|
46
|
+
}
|
47
|
+
}
|
48
|
+
|
49
|
+
// ---------------------------------------------------------------------- Method
|
50
|
+
|
51
|
+
/**
|
52
|
+
* Get an Iterator object that can be used to iterate over all
|
53
|
+
* [ path, value ] entries in the object
|
54
|
+
*
|
55
|
+
* @param {Object} obj - Object to iterate
|
56
|
+
*
|
57
|
+
* @param {Object} [options] - Iteration options
|
58
|
+
*
|
59
|
+
* @param {boolean} [options.walkArrays=false]
|
60
|
+
* If set to true, the iterator will also iterate through Array objects
|
61
|
+
*
|
62
|
+
* @param {object} [options.expandPathKeys=false]
|
63
|
+
* If true, keys in the root object like "some.path.to" will be interpreted
|
64
|
+
* as paths in the object
|
65
|
+
*
|
66
|
+
* @param {object} [options.outputIntermediateNodes=false]
|
67
|
+
* If true, intermediate object nodes (not leaves) will be outputted too
|
68
|
+
*
|
69
|
+
* @param {object} [options.ignoreEmptyObjectLeaves=false]
|
70
|
+
* If true, no output will be generated for empty objects at the leaves of
|
71
|
+
* the object tree
|
72
|
+
*
|
73
|
+
* @return {Iterator} iterator object
|
74
|
+
*/
|
75
|
+
export function iterateObjectEntries(obj, options = {}) {
|
76
|
+
let objectIterator;
|
77
|
+
|
78
|
+
const depthFirst = undefined === options.depthFirst ? true : options.depthFirst;
|
79
|
+
|
80
|
+
options = Object.assign({}, options);
|
81
|
+
|
82
|
+
delete options.depthFirst;
|
83
|
+
|
84
|
+
if (depthFirst) {
|
85
|
+
objectIterator = new IterableTree(obj, options);
|
86
|
+
} else {
|
87
|
+
throw new Error('NOT IMPLEMENTED YET');
|
88
|
+
|
89
|
+
// objectIterator
|
90
|
+
// = new hk.iterate._BreadthFirstIterableTree( obj, options );
|
91
|
+
}
|
92
|
+
|
93
|
+
return objectIterator.entries(); /* entry = [ arrPath, value ] */
|
94
|
+
}
|
95
|
+
|
96
|
+
// ---------------------------------------------------------------------- Method
|
97
|
+
|
98
|
+
/**
|
99
|
+
* Get an Iterator object that can be used to iterate over all paths in
|
100
|
+
* the object
|
101
|
+
*
|
102
|
+
* @param {Object} obj - Object to iterate
|
103
|
+
*
|
104
|
+
* @param {Object} [options] - Iteration options
|
105
|
+
*
|
106
|
+
* @param {boolean} [options.walkArrays=false]
|
107
|
+
* If set to true, the iterator will also iterate through Array objects
|
108
|
+
*
|
109
|
+
* @param {object} [options.expandPathKeys=false]
|
110
|
+
* If true, keys in the root object like "some.path.to" will be interpreted
|
111
|
+
* as paths in the object
|
112
|
+
*
|
113
|
+
* @param {object} [options.outputIntermediateNodes=false]
|
114
|
+
* If true, intermediate object nodes (not leaves) will be outputted too
|
115
|
+
*
|
116
|
+
* @param {object} [options.ignoreEmptyObjectLeaves=false]
|
117
|
+
* If true, no output will be generated for empty objects at the leaves of
|
118
|
+
* the object tree
|
119
|
+
*
|
120
|
+
* @return {Iterator} iterator object
|
121
|
+
*/
|
122
|
+
export function iterateObjectPaths(obj, options = {}) {
|
123
|
+
let objectIterator;
|
124
|
+
|
125
|
+
const depthFirst = undefined === options.depthFirst ? true : options.depthFirst;
|
126
|
+
|
127
|
+
options = Object.assign({}, options);
|
128
|
+
|
129
|
+
delete options.depthFirst;
|
130
|
+
|
131
|
+
if (depthFirst) {
|
132
|
+
objectIterator = new IterableTree(obj, options);
|
133
|
+
} else {
|
134
|
+
throw new Error('NOT IMPLEMENTED YET');
|
135
|
+
|
136
|
+
// objectIterator
|
137
|
+
// = new hk.iterate._BreadthFirstIterableTree( obj, options );
|
138
|
+
}
|
139
|
+
|
140
|
+
return objectIterator.paths();
|
141
|
+
}
|
142
|
+
|
143
|
+
// ---------------------------------------------------------------------- Method
|
144
|
+
|
145
|
+
/**
|
146
|
+
* Get an Iterator object that can be used to iterate over all values in
|
147
|
+
* the object (at the leaves of the object tree)
|
148
|
+
*
|
149
|
+
* @param {Object} obj - Object to iterate
|
150
|
+
*
|
151
|
+
* @param {Object} [options] - Iteration options
|
152
|
+
*
|
153
|
+
* @param {boolean} [options.walkArrays=false]
|
154
|
+
* If set to true, the iterator will also iterate through Array objects
|
155
|
+
*
|
156
|
+
* @param {object} [options.expandPathKeys=false]
|
157
|
+
* If true, keys in the root object like "some.path.to" will be interpreted
|
158
|
+
* as paths in the object
|
159
|
+
*
|
160
|
+
* @param {object} [options.outputIntermediateNodes=false]
|
161
|
+
* If true, intermediate object nodes (not leaves) will be outputted too
|
162
|
+
*
|
163
|
+
* @param {object} [options.ignoreEmptyObjectLeaves=false]
|
164
|
+
* If true, no output will be generated for empty objects at the leaves of
|
165
|
+
* the object tree
|
166
|
+
*
|
167
|
+
* @return {Iterator} iterator object
|
168
|
+
*/
|
169
|
+
export function iterateObjectValues(obj, options) {
|
170
|
+
const objectIterator = new IterableTree(obj, options);
|
171
|
+
|
172
|
+
return objectIterator.values();
|
173
|
+
}
|
174
|
+
|
175
|
+
// ---------------------------------------------------------------------- Method
|
176
|
+
|
177
|
+
/**
|
178
|
+
* Get a list of objects returned by an iterator in sorted order
|
179
|
+
*
|
180
|
+
* --
|
181
|
+
*
|
182
|
+
* @note Sorting requires that all values are evaluated, so all items must be
|
183
|
+
* iterated
|
184
|
+
*
|
185
|
+
* --
|
186
|
+
*
|
187
|
+
* @param {Iterable} it - Iterable items
|
188
|
+
*
|
189
|
+
* @param {function} getValueFn
|
190
|
+
* Function that gets the value from the iterated objects
|
191
|
+
*
|
192
|
+
* @param {boolean} [reversed=false]
|
193
|
+
* Sort in reversed order
|
194
|
+
*
|
195
|
+
*
|
196
|
+
* @returns {array} objects outputted in sorted order
|
197
|
+
*/
|
198
|
+
export async function sortObjects({ it, getValueFn, reversed = false }) {
|
199
|
+
expect.iterable(it);
|
200
|
+
expect.function(getValueFn);
|
201
|
+
|
202
|
+
const allItems = [];
|
203
|
+
const valuesByItem = new WeakMap();
|
204
|
+
|
205
|
+
// -- Gather all items and sort values in arrays
|
206
|
+
|
207
|
+
for (const item of it) {
|
208
|
+
allItems.push(item);
|
209
|
+
valuesByItem.set(item, getValueFn(item));
|
210
|
+
}
|
211
|
+
|
212
|
+
// console.log( { sortValues } );
|
213
|
+
|
214
|
+
// -- Sort all items using sortValues
|
215
|
+
|
216
|
+
let compareFn;
|
217
|
+
|
218
|
+
if (!reversed) {
|
219
|
+
compareFn = smallestFirst;
|
220
|
+
} else {
|
221
|
+
compareFn = largestFirst;
|
222
|
+
}
|
223
|
+
|
224
|
+
allItems.sort((itemA, itemB) => {
|
225
|
+
const valueA = valuesByItem.get(itemA);
|
226
|
+
const valueB = valuesByItem.get(itemB);
|
227
|
+
|
228
|
+
return compareFn(valueA, valueB);
|
229
|
+
});
|
230
|
+
|
231
|
+
// -- Return result
|
232
|
+
|
233
|
+
return allItems;
|
234
|
+
}
|