@thi.ng/arrays 2.7.7 → 2.7.9
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/CHANGELOG.md +1 -1
- package/api.js +0 -1
- package/arg-sort.js +4 -28
- package/argmin.js +14 -40
- package/binary-search.js +69 -176
- package/bisect.js +10 -21
- package/blit.js +33 -30
- package/ends-with.js +11 -24
- package/ensure-array.js +6 -20
- package/ensure-iterable.js +6 -10
- package/fill-range.js +12 -33
- package/find.js +13 -26
- package/floyd-rivest.js +45 -65
- package/fuzzy-match.js +21 -36
- package/insert.js +11 -34
- package/into.js +10 -15
- package/is-sorted.js +12 -34
- package/iterator.js +12 -22
- package/levenshtein.js +90 -136
- package/package.json +13 -10
- package/peek.js +6 -12
- package/quicksort.js +22 -19
- package/rotate.js +24 -40
- package/shuffle.js +18 -35
- package/sort-cached.js +8 -32
- package/starts-with.js +11 -24
- package/swap.js +39 -71
- package/swizzle.js +33 -55
- package/threshold.js +16 -48
- package/topo-sort.js +22 -52
package/quicksort.js
CHANGED
|
@@ -1,23 +1,26 @@
|
|
|
1
1
|
import { compare } from "@thi.ng/compare/compare";
|
|
2
2
|
import { swap } from "./swap.js";
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
}
|
|
19
|
-
quickSort(arr, _cmp, _swap, start, e);
|
|
20
|
-
quickSort(arr, _cmp, _swap, e + 1, end);
|
|
3
|
+
function quickSort(arr, _cmp = compare, _swap = swap, start = 0, end = arr.length - 1) {
|
|
4
|
+
if (start < end) {
|
|
5
|
+
const pivot = arr[start + (end - start >> 1)];
|
|
6
|
+
let s = start - 1;
|
|
7
|
+
let e = end + 1;
|
|
8
|
+
while (true) {
|
|
9
|
+
do {
|
|
10
|
+
s++;
|
|
11
|
+
} while (_cmp(arr[s], pivot) < 0);
|
|
12
|
+
do {
|
|
13
|
+
e--;
|
|
14
|
+
} while (_cmp(arr[e], pivot) > 0);
|
|
15
|
+
if (s >= e)
|
|
16
|
+
break;
|
|
17
|
+
_swap(arr, s, e);
|
|
21
18
|
}
|
|
22
|
-
|
|
19
|
+
quickSort(arr, _cmp, _swap, start, e);
|
|
20
|
+
quickSort(arr, _cmp, _swap, e + 1, end);
|
|
21
|
+
}
|
|
22
|
+
return arr;
|
|
23
23
|
}
|
|
24
|
+
export {
|
|
25
|
+
quickSort
|
|
26
|
+
};
|
package/rotate.js
CHANGED
|
@@ -1,45 +1,29 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
* the beginning of the array), otherwise to the right (end). The rotation
|
|
4
|
-
* distance will be `num % buf.length`. The function is no-op if the resulting
|
|
5
|
-
* distance is zero or `buf` is empty.
|
|
6
|
-
*
|
|
7
|
-
* @remarks
|
|
8
|
-
* Not suitable for typed arrays. Use {@link rotateTyped} for those.
|
|
9
|
-
*
|
|
10
|
-
* @param buf
|
|
11
|
-
* @param num
|
|
12
|
-
*/
|
|
13
|
-
export const rotate = (buf, num) => {
|
|
14
|
-
if (!(num = __distance(buf, num)))
|
|
15
|
-
return buf;
|
|
16
|
-
if (num < 0) {
|
|
17
|
-
buf.push(...buf.splice(0, -num));
|
|
18
|
-
}
|
|
19
|
-
else {
|
|
20
|
-
buf.unshift(...buf.splice(-num));
|
|
21
|
-
}
|
|
1
|
+
const rotate = (buf, num) => {
|
|
2
|
+
if (!(num = __distance(buf, num)))
|
|
22
3
|
return buf;
|
|
4
|
+
if (num < 0) {
|
|
5
|
+
buf.push(...buf.splice(0, -num));
|
|
6
|
+
} else {
|
|
7
|
+
buf.unshift(...buf.splice(-num));
|
|
8
|
+
}
|
|
9
|
+
return buf;
|
|
23
10
|
};
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
*
|
|
27
|
-
* @param buf
|
|
28
|
-
* @param num
|
|
29
|
-
*/
|
|
30
|
-
export const rotateTyped = (buf, num) => {
|
|
31
|
-
if (!(num = __distance(buf, num)))
|
|
32
|
-
return buf;
|
|
33
|
-
if (num < 0) {
|
|
34
|
-
const tmp = buf.slice(0, -num);
|
|
35
|
-
buf.copyWithin(0, -num);
|
|
36
|
-
buf.set(tmp, buf.length + num);
|
|
37
|
-
}
|
|
38
|
-
else if (num > 0) {
|
|
39
|
-
const tmp = buf.slice(buf.length - num);
|
|
40
|
-
buf.copyWithin(num, 0);
|
|
41
|
-
buf.set(tmp, 0);
|
|
42
|
-
}
|
|
11
|
+
const rotateTyped = (buf, num) => {
|
|
12
|
+
if (!(num = __distance(buf, num)))
|
|
43
13
|
return buf;
|
|
14
|
+
if (num < 0) {
|
|
15
|
+
const tmp = buf.slice(0, -num);
|
|
16
|
+
buf.copyWithin(0, -num);
|
|
17
|
+
buf.set(tmp, buf.length + num);
|
|
18
|
+
} else if (num > 0) {
|
|
19
|
+
const tmp = buf.slice(buf.length - num);
|
|
20
|
+
buf.copyWithin(num, 0);
|
|
21
|
+
buf.set(tmp, 0);
|
|
22
|
+
}
|
|
23
|
+
return buf;
|
|
44
24
|
};
|
|
45
25
|
const __distance = (buf, num) => buf.length ? (num | 0) % buf.length : 0;
|
|
26
|
+
export {
|
|
27
|
+
rotate,
|
|
28
|
+
rotateTyped
|
|
29
|
+
};
|
package/shuffle.js
CHANGED
|
@@ -1,39 +1,22 @@
|
|
|
1
1
|
import { assert } from "@thi.ng/errors/assert";
|
|
2
2
|
import { SYSTEM } from "@thi.ng/random/system";
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
* @param n - num items
|
|
15
|
-
* @param rnd - PRNG
|
|
16
|
-
*/
|
|
17
|
-
export const shuffleRange = (buf, start = 0, end = buf.length, rnd = SYSTEM) => {
|
|
18
|
-
assert(start >= 0 && end >= start && end <= buf.length, `illegal range ${start}..${end}`);
|
|
19
|
-
if (end - start > 1) {
|
|
20
|
-
for (let i = end; i-- > start;) {
|
|
21
|
-
const a = rnd.minmax(start, i + 1) | 0;
|
|
22
|
-
const t = buf[a];
|
|
23
|
-
buf[a] = buf[i];
|
|
24
|
-
buf[i] = t;
|
|
25
|
-
}
|
|
3
|
+
const shuffleRange = (buf, start = 0, end = buf.length, rnd = SYSTEM) => {
|
|
4
|
+
assert(
|
|
5
|
+
start >= 0 && end >= start && end <= buf.length,
|
|
6
|
+
`illegal range ${start}..${end}`
|
|
7
|
+
);
|
|
8
|
+
if (end - start > 1) {
|
|
9
|
+
for (let i = end; i-- > start; ) {
|
|
10
|
+
const a = rnd.minmax(start, i + 1) | 0;
|
|
11
|
+
const t = buf[a];
|
|
12
|
+
buf[a] = buf[i];
|
|
13
|
+
buf[i] = t;
|
|
26
14
|
}
|
|
27
|
-
|
|
15
|
+
}
|
|
16
|
+
return buf;
|
|
17
|
+
};
|
|
18
|
+
const shuffle = (buf, n = buf.length, rnd = SYSTEM) => shuffleRange(buf, 0, n, rnd);
|
|
19
|
+
export {
|
|
20
|
+
shuffle,
|
|
21
|
+
shuffleRange
|
|
28
22
|
};
|
|
29
|
-
/**
|
|
30
|
-
* Applies {@link shuffleRange} to the given array. If `n` is given,
|
|
31
|
-
* only the first `n` items are shuffled. Mutates original array.
|
|
32
|
-
*
|
|
33
|
-
* {@link shuffleRange}
|
|
34
|
-
*
|
|
35
|
-
* @param buf - array
|
|
36
|
-
* @param n - num items
|
|
37
|
-
* @param rnd - PRNG
|
|
38
|
-
*/
|
|
39
|
-
export const shuffle = (buf, n = buf.length, rnd = SYSTEM) => shuffleRange(buf, 0, n, rnd);
|
package/sort-cached.js
CHANGED
|
@@ -3,36 +3,12 @@ import { compare } from "@thi.ng/compare/compare";
|
|
|
3
3
|
import { assert } from "@thi.ng/errors/assert";
|
|
4
4
|
import { quickSort } from "./quicksort.js";
|
|
5
5
|
import { multiSwap } from "./swap.js";
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
* This function is primarily intended for use cases where an array needs to be
|
|
15
|
-
* sorted based on the item order of another array, or where sort keys are
|
|
16
|
-
* derived from non-trivial computations and need to be cached, rather than be
|
|
17
|
-
* re-evaluated multiple times from within a comparator.
|
|
18
|
-
*
|
|
19
|
-
* @example
|
|
20
|
-
* ```ts
|
|
21
|
-
* // sort by length in descending order
|
|
22
|
-
* sortByCachedKey(["a","bbbb","ccc","dd"], (x) => x.length, (a, b) => b - a);
|
|
23
|
-
* // [ 'bbbb', 'ccc', 'dd', 'a' ]
|
|
24
|
-
*
|
|
25
|
-
* sortByCachedKey(["a", "b", "c", "d"], [3, 2, 1, 0])
|
|
26
|
-
* // [ 'd', 'c', 'b', 'a' ]
|
|
27
|
-
* ```
|
|
28
|
-
*
|
|
29
|
-
* @param src -
|
|
30
|
-
* @param key -
|
|
31
|
-
* @param cmp -
|
|
32
|
-
*/
|
|
33
|
-
export const sortByCachedKey = (src, key, cmp = compare) => {
|
|
34
|
-
const keys = isFunction(key) ? src.map(key) : key;
|
|
35
|
-
assert(keys.length === src.length, `keys.length != src.length`);
|
|
36
|
-
quickSort(keys, cmp, multiSwap(src));
|
|
37
|
-
return src;
|
|
6
|
+
const sortByCachedKey = (src, key, cmp = compare) => {
|
|
7
|
+
const keys = isFunction(key) ? src.map(key) : key;
|
|
8
|
+
assert(keys.length === src.length, `keys.length != src.length`);
|
|
9
|
+
quickSort(keys, cmp, multiSwap(src));
|
|
10
|
+
return src;
|
|
11
|
+
};
|
|
12
|
+
export {
|
|
13
|
+
sortByCachedKey
|
|
38
14
|
};
|
package/starts-with.js
CHANGED
|
@@ -1,26 +1,13 @@
|
|
|
1
1
|
import { equiv as _eq } from "@thi.ng/equiv";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
* {@link endsWith}
|
|
14
|
-
*
|
|
15
|
-
* @param buf - array
|
|
16
|
-
* @param needle - search value
|
|
17
|
-
* @param equiv - equivalence predicate
|
|
18
|
-
*/
|
|
19
|
-
export const startsWith = (buf, needle, equiv = _eq) => {
|
|
20
|
-
let i = buf.length;
|
|
21
|
-
let j = needle.length;
|
|
22
|
-
if (i < j)
|
|
23
|
-
return false;
|
|
24
|
-
while (-j >= 0 && equiv(buf[j], needle[j])) { }
|
|
25
|
-
return j < 0;
|
|
2
|
+
const startsWith = (buf, needle, equiv = _eq) => {
|
|
3
|
+
let i = buf.length;
|
|
4
|
+
let j = needle.length;
|
|
5
|
+
if (i < j)
|
|
6
|
+
return false;
|
|
7
|
+
while (-j >= 0 && equiv(buf[j], needle[j])) {
|
|
8
|
+
}
|
|
9
|
+
return j < 0;
|
|
10
|
+
};
|
|
11
|
+
export {
|
|
12
|
+
startsWith
|
|
26
13
|
};
|
package/swap.js
CHANGED
|
@@ -1,73 +1,41 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
* @param x - first index
|
|
6
|
-
* @param y - other index
|
|
7
|
-
*/
|
|
8
|
-
export const swap = (arr, x, y) => {
|
|
9
|
-
const t = arr[x];
|
|
10
|
-
arr[x] = arr[y];
|
|
11
|
-
arr[y] = t;
|
|
1
|
+
const swap = (arr, x, y) => {
|
|
2
|
+
const t = arr[x];
|
|
3
|
+
arr[x] = arr[y];
|
|
4
|
+
arr[y] = t;
|
|
12
5
|
};
|
|
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
|
-
case 1:
|
|
49
|
-
return (a, x, y) => {
|
|
50
|
-
swap(a, x, y);
|
|
51
|
-
swap(b, x, y);
|
|
52
|
-
};
|
|
53
|
-
case 2:
|
|
54
|
-
return (a, x, y) => {
|
|
55
|
-
swap(a, x, y);
|
|
56
|
-
swap(b, x, y);
|
|
57
|
-
swap(c, x, y);
|
|
58
|
-
};
|
|
59
|
-
case 3:
|
|
60
|
-
return (a, x, y) => {
|
|
61
|
-
swap(a, x, y);
|
|
62
|
-
swap(b, x, y);
|
|
63
|
-
swap(c, x, y);
|
|
64
|
-
swap(d, x, y);
|
|
65
|
-
};
|
|
66
|
-
default:
|
|
67
|
-
return (a, x, y) => {
|
|
68
|
-
swap(a, x, y);
|
|
69
|
-
for (let i = n; i-- > 0;)
|
|
70
|
-
swap(xs[i], x, y);
|
|
71
|
-
};
|
|
72
|
-
}
|
|
6
|
+
const multiSwap = (...xs) => {
|
|
7
|
+
const [b, c, d] = xs;
|
|
8
|
+
const n = xs.length;
|
|
9
|
+
switch (n) {
|
|
10
|
+
case 0:
|
|
11
|
+
return swap;
|
|
12
|
+
case 1:
|
|
13
|
+
return (a, x, y) => {
|
|
14
|
+
swap(a, x, y);
|
|
15
|
+
swap(b, x, y);
|
|
16
|
+
};
|
|
17
|
+
case 2:
|
|
18
|
+
return (a, x, y) => {
|
|
19
|
+
swap(a, x, y);
|
|
20
|
+
swap(b, x, y);
|
|
21
|
+
swap(c, x, y);
|
|
22
|
+
};
|
|
23
|
+
case 3:
|
|
24
|
+
return (a, x, y) => {
|
|
25
|
+
swap(a, x, y);
|
|
26
|
+
swap(b, x, y);
|
|
27
|
+
swap(c, x, y);
|
|
28
|
+
swap(d, x, y);
|
|
29
|
+
};
|
|
30
|
+
default:
|
|
31
|
+
return (a, x, y) => {
|
|
32
|
+
swap(a, x, y);
|
|
33
|
+
for (let i = n; i-- > 0; )
|
|
34
|
+
swap(xs[i], x, y);
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
export {
|
|
39
|
+
multiSwap,
|
|
40
|
+
swap
|
|
73
41
|
};
|
package/swizzle.js
CHANGED
|
@@ -1,56 +1,34 @@
|
|
|
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
|
-
return (x) => [x[a], x[b]];
|
|
35
|
-
case 3:
|
|
36
|
-
return (x) => [x[a], x[b], x[c]];
|
|
37
|
-
case 4:
|
|
38
|
-
return (x) => [x[a], x[b], x[c], x[d]];
|
|
39
|
-
case 5:
|
|
40
|
-
return (x) => [x[a], x[b], x[c], x[d], x[e]];
|
|
41
|
-
case 6:
|
|
42
|
-
return (x) => [x[a], x[b], x[c], x[d], x[e], x[f]];
|
|
43
|
-
case 7:
|
|
44
|
-
return (x) => [x[a], x[b], x[c], x[d], x[e], x[f], x[g]];
|
|
45
|
-
case 8:
|
|
46
|
-
return (x) => [x[a], x[b], x[c], x[d], x[e], x[f], x[g], x[h]];
|
|
47
|
-
default:
|
|
48
|
-
return (x) => {
|
|
49
|
-
const res = [];
|
|
50
|
-
for (let i = order.length; i-- > 0;) {
|
|
51
|
-
res[i] = x[order[i]];
|
|
52
|
-
}
|
|
53
|
-
return res;
|
|
54
|
-
};
|
|
55
|
-
}
|
|
1
|
+
const swizzle = (order) => {
|
|
2
|
+
const [a, b, c, d, e, f, g, h] = order;
|
|
3
|
+
switch (order.length) {
|
|
4
|
+
case 0:
|
|
5
|
+
return () => [];
|
|
6
|
+
case 1:
|
|
7
|
+
return (x) => [x[a]];
|
|
8
|
+
case 2:
|
|
9
|
+
return (x) => [x[a], x[b]];
|
|
10
|
+
case 3:
|
|
11
|
+
return (x) => [x[a], x[b], x[c]];
|
|
12
|
+
case 4:
|
|
13
|
+
return (x) => [x[a], x[b], x[c], x[d]];
|
|
14
|
+
case 5:
|
|
15
|
+
return (x) => [x[a], x[b], x[c], x[d], x[e]];
|
|
16
|
+
case 6:
|
|
17
|
+
return (x) => [x[a], x[b], x[c], x[d], x[e], x[f]];
|
|
18
|
+
case 7:
|
|
19
|
+
return (x) => [x[a], x[b], x[c], x[d], x[e], x[f], x[g]];
|
|
20
|
+
case 8:
|
|
21
|
+
return (x) => [x[a], x[b], x[c], x[d], x[e], x[f], x[g], x[h]];
|
|
22
|
+
default:
|
|
23
|
+
return (x) => {
|
|
24
|
+
const res = [];
|
|
25
|
+
for (let i = order.length; i-- > 0; ) {
|
|
26
|
+
res[i] = x[order[i]];
|
|
27
|
+
}
|
|
28
|
+
return res;
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
export {
|
|
33
|
+
swizzle
|
|
56
34
|
};
|
package/threshold.js
CHANGED
|
@@ -1,50 +1,18 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
* @remarks
|
|
8
|
-
* The thresholds will be sorted & matched in ascending order using `<=`
|
|
9
|
-
* comparison.
|
|
10
|
-
*
|
|
11
|
-
* @example
|
|
12
|
-
* ```ts
|
|
13
|
-
* const numColumns = selectThresholdMin({ 480: 1, 640: 2, 960: 3 }, 4);
|
|
14
|
-
*
|
|
15
|
-
* numColumns(320) // 1
|
|
16
|
-
*
|
|
17
|
-
* numColumns(481) // 2
|
|
18
|
-
*
|
|
19
|
-
* numColumns(768) // 3
|
|
20
|
-
*
|
|
21
|
-
* numColumns(1024) // 4
|
|
22
|
-
* ```
|
|
23
|
-
*
|
|
24
|
-
* @param thresholds
|
|
25
|
-
* @param defaultVal
|
|
26
|
-
*/
|
|
27
|
-
export const selectThresholdMin = (thresholds, defaultVal) => {
|
|
28
|
-
const $thresholds = Object.entries(thresholds)
|
|
29
|
-
.map(([k, v]) => [+k, v])
|
|
30
|
-
.sort((a, b) => a[0] - b[0]);
|
|
31
|
-
return (x) => {
|
|
32
|
-
const res = $thresholds.find((t) => x <= t[0]);
|
|
33
|
-
return res ? res[1] : defaultVal;
|
|
34
|
-
};
|
|
1
|
+
const selectThresholdMin = (thresholds, defaultVal) => {
|
|
2
|
+
const $thresholds = Object.entries(thresholds).map(([k, v]) => [+k, v]).sort((a, b) => a[0] - b[0]);
|
|
3
|
+
return (x) => {
|
|
4
|
+
const res = $thresholds.find((t) => x <= t[0]);
|
|
5
|
+
return res ? res[1] : defaultVal;
|
|
6
|
+
};
|
|
35
7
|
};
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
return (x) => {
|
|
47
|
-
const res = $thresholds.find((t) => x >= t[0]);
|
|
48
|
-
return res ? res[1] : defaultVal;
|
|
49
|
-
};
|
|
8
|
+
const selectThresholdMax = (thresholds, defaultVal) => {
|
|
9
|
+
const $thresholds = Object.entries(thresholds).map(([k, v]) => [+k, v]).sort((a, b) => b[0] - a[0]);
|
|
10
|
+
return (x) => {
|
|
11
|
+
const res = $thresholds.find((t) => x >= t[0]);
|
|
12
|
+
return res ? res[1] : defaultVal;
|
|
13
|
+
};
|
|
14
|
+
};
|
|
15
|
+
export {
|
|
16
|
+
selectThresholdMax,
|
|
17
|
+
selectThresholdMin
|
|
50
18
|
};
|
package/topo-sort.js
CHANGED
|
@@ -1,54 +1,24 @@
|
|
|
1
1
|
import { illegalState } from "@thi.ng/errors";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
* // An error will be thrown if the graph contains cycles...
|
|
25
|
-
* graph.d.deps.push("a");
|
|
26
|
-
*
|
|
27
|
-
* topoSort(graph, (node) => node.deps);
|
|
28
|
-
* // Uncaught Error: illegal state: dependency cycle: a -> c -> d -> a
|
|
29
|
-
* ```
|
|
30
|
-
*
|
|
31
|
-
* @param nodes
|
|
32
|
-
* @param deps
|
|
33
|
-
* @returns
|
|
34
|
-
*/
|
|
35
|
-
export const topoSort = (nodes, deps) => {
|
|
36
|
-
const cycles = {};
|
|
37
|
-
const topology = [];
|
|
38
|
-
const sort = (id, path) => {
|
|
39
|
-
if (cycles[id])
|
|
40
|
-
illegalState(`dependency cycle: ${path.join(" -> ")}`);
|
|
41
|
-
cycles[id] = true;
|
|
42
|
-
const nodeDeps = deps(nodes[id]);
|
|
43
|
-
if (nodeDeps) {
|
|
44
|
-
for (let d of nodeDeps)
|
|
45
|
-
sort(d, [...path, d]);
|
|
46
|
-
}
|
|
47
|
-
cycles[id] = false;
|
|
48
|
-
if (!topology.includes(id))
|
|
49
|
-
topology.push(id);
|
|
50
|
-
};
|
|
51
|
-
for (let id in nodes)
|
|
52
|
-
sort(id, [id]);
|
|
53
|
-
return topology;
|
|
2
|
+
const topoSort = (nodes, deps) => {
|
|
3
|
+
const cycles = {};
|
|
4
|
+
const topology = [];
|
|
5
|
+
const sort = (id, path) => {
|
|
6
|
+
if (cycles[id])
|
|
7
|
+
illegalState(`dependency cycle: ${path.join(" -> ")}`);
|
|
8
|
+
cycles[id] = true;
|
|
9
|
+
const nodeDeps = deps(nodes[id]);
|
|
10
|
+
if (nodeDeps) {
|
|
11
|
+
for (let d of nodeDeps)
|
|
12
|
+
sort(d, [...path, d]);
|
|
13
|
+
}
|
|
14
|
+
cycles[id] = false;
|
|
15
|
+
if (!topology.includes(id))
|
|
16
|
+
topology.push(id);
|
|
17
|
+
};
|
|
18
|
+
for (let id in nodes)
|
|
19
|
+
sort(id, [id]);
|
|
20
|
+
return topology;
|
|
21
|
+
};
|
|
22
|
+
export {
|
|
23
|
+
topoSort
|
|
54
24
|
};
|