atomic-fns 0.2.0 → 0.2.2
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/.esdoc.json +19 -1
- package/.eslintrc.json +1 -0
- package/README.md +3 -6
- package/package.json +6 -5
- package/src/collections.d.ts +4 -0
- package/src/collections.js +422 -439
- package/src/collections.ts +6 -2
- package/src/datetime.d.ts +4 -0
- package/src/datetime.js +5 -1
- package/src/datetime.ts +5 -0
- package/src/functools.d.ts +4 -0
- package/src/functools.js +45 -46
- package/src/functools.ts +4 -0
- package/src/globals.d.ts +7 -3
- package/src/globals.js +175 -195
- package/src/globals.ts +8 -4
- package/src/index.js +7 -7
- package/src/itertools.d.ts +4 -0
- package/src/itertools.js +51 -54
- package/src/itertools.ts +4 -0
- package/src/math.js +45 -42
- package/src/math.ts +4 -0
- package/src/objects.js +1 -1
- package/src/operators.js +73 -92
- package/src/operators.ts +4 -0
- package/src/random.js +26 -26
- package/src/random.ts +5 -1
- package/src/strings.js +1 -1
- package/src/util.js +1 -1
- package/tests/collections.spec.ts +81 -9
- package/tests/globals.spec.ts +40 -2
- package/tests/itertools.spec.ts +17 -10
- package/tests/operators.spec.ts +8 -5
- package/tsconfig.json +10 -2
package/src/itertools.js
CHANGED
|
@@ -1,29 +1,31 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Iterators
|
|
3
|
+
* @module
|
|
4
|
+
*/
|
|
5
|
+
import { isObject, len } from './globals.js'
|
|
6
|
+
import { comp, id } from './operators.js'
|
|
7
|
+
const compKey = (cmp, key) => (x, y) => cmp(key(x), key(y))
|
|
4
8
|
export function* range(...args) {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
}
|
|
9
|
+
if (args.length === 1) {
|
|
10
|
+
const stop = args[0]
|
|
11
|
+
for (let i = 0; i < stop; i++) {
|
|
12
|
+
yield i
|
|
10
13
|
}
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
}
|
|
14
|
+
} else if (args.length === 2) {
|
|
15
|
+
let [start, stop] = args
|
|
16
|
+
for (; start < stop; start++) {
|
|
17
|
+
yield start
|
|
16
18
|
}
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
}
|
|
19
|
+
} else {
|
|
20
|
+
let [start, stop, step] = args
|
|
21
|
+
for (; start < stop; start += step) {
|
|
22
|
+
yield start
|
|
22
23
|
}
|
|
24
|
+
}
|
|
23
25
|
}
|
|
24
26
|
/** Creates a new list with the elements from the iterable in reverse order. */
|
|
25
27
|
export function reversed(iterable) {
|
|
26
|
-
|
|
28
|
+
return Array.from(iterable).reverse()
|
|
27
29
|
}
|
|
28
30
|
/**
|
|
29
31
|
* Creates a new list from `args` and sorts it. This can be called many ways:
|
|
@@ -43,24 +45,21 @@ export function reversed(iterable) {
|
|
|
43
45
|
* @return
|
|
44
46
|
*/
|
|
45
47
|
export function sorted(args, key, reverse, compareFn) {
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
if (typeof
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
else {
|
|
54
|
-
reverse = true;
|
|
55
|
-
}
|
|
56
|
-
key = id;
|
|
48
|
+
if (isObject(args)) args = Object.keys(args)
|
|
49
|
+
if (typeof key === 'boolean') {
|
|
50
|
+
if (typeof reverse === 'function') {
|
|
51
|
+
compareFn = reverse
|
|
52
|
+
reverse = false
|
|
53
|
+
} else {
|
|
54
|
+
reverse = true
|
|
57
55
|
}
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
56
|
+
key = id
|
|
57
|
+
}
|
|
58
|
+
const copy = Array.from(args)
|
|
59
|
+
const _compare = compKey(compareFn || comp, key || id)
|
|
60
|
+
copy.sort(_compare)
|
|
61
|
+
if (reverse) copy.reverse()
|
|
62
|
+
return copy
|
|
64
63
|
}
|
|
65
64
|
/**
|
|
66
65
|
* Sort `args` in place. Can be called like this:
|
|
@@ -74,28 +73,26 @@ export function sorted(args, key, reverse, compareFn) {
|
|
|
74
73
|
* @return
|
|
75
74
|
*/
|
|
76
75
|
export function sort(args, reverse, compareFn) {
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
return args;
|
|
76
|
+
if (typeof reverse === 'function') {
|
|
77
|
+
compareFn = reverse
|
|
78
|
+
reverse = false
|
|
79
|
+
}
|
|
80
|
+
args.sort(compareFn || comp)
|
|
81
|
+
if (reverse === true) args.reverse()
|
|
82
|
+
return args
|
|
85
83
|
}
|
|
86
84
|
/** Returns a generator that calls `fn(index)` for each index < n */
|
|
87
85
|
export function* times(n, fn) {
|
|
88
|
-
|
|
89
|
-
yield fn(i);
|
|
86
|
+
for (let i = 0; i < n; i++) yield fn(i)
|
|
90
87
|
}
|
|
91
88
|
export function* zip(...args) {
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
}
|
|
99
|
-
yield tuple;
|
|
89
|
+
const size = len(args[0])
|
|
90
|
+
for (let i = 0; i < size; i++) {
|
|
91
|
+
const tuple = []
|
|
92
|
+
for (let k = 0; k < args.length; k++) {
|
|
93
|
+
const item = args[k][i]
|
|
94
|
+
tuple.push(item)
|
|
100
95
|
}
|
|
96
|
+
yield tuple
|
|
97
|
+
}
|
|
101
98
|
}
|
package/src/itertools.ts
CHANGED
package/src/math.js
CHANGED
|
@@ -1,10 +1,13 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Math
|
|
3
|
+
* @module
|
|
4
|
+
*/
|
|
5
|
+
import { call, isFunc } from './globals.js'
|
|
6
|
+
import { comp } from './operators.js'
|
|
3
7
|
export function abs(x) {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
return Math.abs(x);
|
|
8
|
+
const op = call(x, 'abs')
|
|
9
|
+
if (op != null) return op
|
|
10
|
+
return Math.abs(x)
|
|
8
11
|
}
|
|
9
12
|
/**
|
|
10
13
|
* Returns a tuple like (x / y, x % y)
|
|
@@ -14,54 +17,54 @@ export function abs(x) {
|
|
|
14
17
|
* @return {number[]}
|
|
15
18
|
*/
|
|
16
19
|
export function divmod(x, y) {
|
|
17
|
-
|
|
20
|
+
return [Math.floor(x / y), x % y]
|
|
18
21
|
}
|
|
19
22
|
export function log2(x) {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
23
|
+
if (x > 0) {
|
|
24
|
+
return Math.log(x) * 1.442695
|
|
25
|
+
}
|
|
26
|
+
return Number.NaN
|
|
24
27
|
}
|
|
25
28
|
export function logBase(x, y) {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
29
|
+
if (x > 0 && y > 0) {
|
|
30
|
+
return Math.log(y) / Math.log(x)
|
|
31
|
+
}
|
|
32
|
+
return Number.NaN
|
|
30
33
|
}
|
|
31
34
|
/** First argument can be a comparer func */
|
|
32
35
|
export function min(args) {
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
36
|
+
// Uses `le` by default
|
|
37
|
+
let cmp = comp
|
|
38
|
+
if (isFunc(args[0])) {
|
|
39
|
+
cmp = args.shift()
|
|
40
|
+
}
|
|
41
|
+
let res = args[0]
|
|
42
|
+
for (const x of args) {
|
|
43
|
+
if (cmp(x, res) === -1) {
|
|
44
|
+
res = x
|
|
37
45
|
}
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
if (cmp(x, res) === -1) {
|
|
41
|
-
res = x;
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
return res;
|
|
46
|
+
}
|
|
47
|
+
return res
|
|
45
48
|
}
|
|
46
49
|
/** First argument can be a comparer func */
|
|
47
50
|
export function max(args) {
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
}
|
|
51
|
+
// Uses ge by default
|
|
52
|
+
let cmp = comp
|
|
53
|
+
if (isFunc(args[0])) {
|
|
54
|
+
cmp = args.shift()
|
|
55
|
+
}
|
|
56
|
+
let res = args[0]
|
|
57
|
+
for (const x of args) {
|
|
58
|
+
if (cmp(x, res) === 1) {
|
|
59
|
+
res = x
|
|
58
60
|
}
|
|
59
|
-
|
|
61
|
+
}
|
|
62
|
+
return res
|
|
60
63
|
}
|
|
61
64
|
export function sum(args) {
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
65
|
+
let total = 0
|
|
66
|
+
for (const x of args) {
|
|
67
|
+
total += x
|
|
68
|
+
}
|
|
69
|
+
return total
|
|
67
70
|
}
|
package/src/math.ts
CHANGED
package/src/objects.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
'use strict'
|
package/src/operators.js
CHANGED
|
@@ -1,116 +1,98 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
export const
|
|
7
|
-
export const
|
|
8
|
-
export const
|
|
9
|
-
export const
|
|
1
|
+
/**
|
|
2
|
+
* Operators
|
|
3
|
+
* @module
|
|
4
|
+
*/
|
|
5
|
+
import { call, isNumber, isObject } from './globals.js'
|
|
6
|
+
export const id = (x) => x
|
|
7
|
+
export const bool = (x) => !!x
|
|
8
|
+
export const not = (x) => !x
|
|
9
|
+
export const isinstance = (x, y) => x instanceof y
|
|
10
|
+
export const all = (arr, fn = bool) => arr.every(fn)
|
|
11
|
+
export const any = (arr, fn = bool) => arr.some(fn)
|
|
12
|
+
export const and = all
|
|
13
|
+
export const or = any
|
|
10
14
|
export function comp(x, y) {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
return -1;
|
|
18
|
-
if (ge(x, y))
|
|
19
|
-
return 1;
|
|
20
|
-
return 0;
|
|
15
|
+
const op = call(x, 'compare', y)
|
|
16
|
+
if (isNumber(op)) return op
|
|
17
|
+
if (eq(x, y)) return 0
|
|
18
|
+
if (le(x, y)) return -1
|
|
19
|
+
if (ge(x, y)) return 1
|
|
20
|
+
return 0
|
|
21
21
|
}
|
|
22
22
|
export function eq(x, y) {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
return x === y;
|
|
23
|
+
const op = call(x, 'eq', y)
|
|
24
|
+
if (op != null) return op
|
|
25
|
+
return x === y
|
|
27
26
|
}
|
|
28
27
|
export function shallowEqual(x, y) {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
if (!eq(x[i], y[i]))
|
|
34
|
-
return false;
|
|
35
|
-
}
|
|
36
|
-
return true;
|
|
28
|
+
if (!x || !y) return x === y
|
|
29
|
+
if (Array.isArray(x)) {
|
|
30
|
+
for (let i = 0; i < x.length; i++) {
|
|
31
|
+
if (!eq(x[i], y[i])) return false
|
|
37
32
|
}
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
}
|
|
45
|
-
return true;
|
|
33
|
+
return true
|
|
34
|
+
}
|
|
35
|
+
if (isObject(x)) {
|
|
36
|
+
if (eq(x, y)) return true
|
|
37
|
+
for (const key in x) {
|
|
38
|
+
if (!eq(x[key], y[key])) return false
|
|
46
39
|
}
|
|
47
|
-
return
|
|
40
|
+
return true
|
|
41
|
+
}
|
|
42
|
+
return eq(x, y)
|
|
48
43
|
}
|
|
49
44
|
export function lt(x, y) {
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
return x < y;
|
|
45
|
+
const op = call(x, 'lt', y)
|
|
46
|
+
if (op != null) return op
|
|
47
|
+
return x < y
|
|
54
48
|
}
|
|
55
49
|
export function le(x, y) {
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
if (op != null)
|
|
64
|
-
return op;
|
|
65
|
-
return x <= y;
|
|
50
|
+
let op = call(x, 'le', y)
|
|
51
|
+
if (op != null) return op
|
|
52
|
+
op = call(x, 'eq', y)
|
|
53
|
+
if (op === true) return op
|
|
54
|
+
op = call(x, 'lt', y)
|
|
55
|
+
if (op != null) return op
|
|
56
|
+
return x <= y
|
|
66
57
|
}
|
|
67
58
|
export function gt(x, y) {
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
return x > y;
|
|
59
|
+
const op = call(x, 'gt', y)
|
|
60
|
+
if (op != null) return op
|
|
61
|
+
return x > y
|
|
72
62
|
}
|
|
73
63
|
export function ge(x, y) {
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
if (op != null)
|
|
82
|
-
return op;
|
|
83
|
-
return x >= y;
|
|
64
|
+
let op = call(x, 'ge', y)
|
|
65
|
+
if (op != null) return op
|
|
66
|
+
op = call(x, 'eq', y)
|
|
67
|
+
if (op === true) return op
|
|
68
|
+
op = call(x, 'gt', y)
|
|
69
|
+
if (op != null) return op
|
|
70
|
+
return x >= y
|
|
84
71
|
}
|
|
85
72
|
export function add(x, y) {
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
return x + y;
|
|
73
|
+
const op = call(x, 'add', y)
|
|
74
|
+
if (op != null) return op
|
|
75
|
+
return x + y
|
|
90
76
|
}
|
|
91
77
|
export function sub(x, y) {
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
return x - y;
|
|
78
|
+
const op = call(x, 'sub', y)
|
|
79
|
+
if (op != null) return op
|
|
80
|
+
return x - y
|
|
96
81
|
}
|
|
97
82
|
export function mult(x, y) {
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
return x * y;
|
|
83
|
+
const op = call(x, 'mult', y)
|
|
84
|
+
if (op != null) return op
|
|
85
|
+
return x * y
|
|
102
86
|
}
|
|
103
87
|
export function div(x, y) {
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
return x / y;
|
|
88
|
+
const op = call(x, 'div', y)
|
|
89
|
+
if (op != null) return op
|
|
90
|
+
return x / y
|
|
108
91
|
}
|
|
109
92
|
export function mod(x, y) {
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
return x % y;
|
|
93
|
+
const op = call(x, 'mod', y)
|
|
94
|
+
if (op != null) return op
|
|
95
|
+
return x % y
|
|
114
96
|
}
|
|
115
97
|
/**
|
|
116
98
|
* Calculates `x` to the power of `y`. If `x` implements a custom `pow` operator
|
|
@@ -121,8 +103,7 @@ export function mod(x, y) {
|
|
|
121
103
|
* @return `x` raised to the power `y`
|
|
122
104
|
*/
|
|
123
105
|
export function pow(x, y) {
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
return x ** y;
|
|
106
|
+
const op = call(x, 'pow', y)
|
|
107
|
+
if (op != null) return op
|
|
108
|
+
return x ** y
|
|
128
109
|
}
|
package/src/operators.ts
CHANGED
package/src/random.js
CHANGED
|
@@ -1,14 +1,17 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Random
|
|
3
|
+
* @module
|
|
4
|
+
*/
|
|
5
|
+
import { isObject } from './globals'
|
|
2
6
|
/** Returns a random float between a [min, max) value (max exclusive). */
|
|
3
|
-
export const random = (min = 0, max = 1) => Math.random() * (max - min) + min
|
|
7
|
+
export const random = (min = 0, max = 1) => Math.random() * (max - min) + min
|
|
4
8
|
/** Returns a random integer between a [min, max] value (inclusive). */
|
|
5
|
-
export const randomInt = (min = 0, max = 1) => Math.round(random(min, max))
|
|
9
|
+
export const randomInt = (min = 0, max = 1) => Math.round(random(min, max))
|
|
6
10
|
/** Returns the item at some random index in a sequence. */
|
|
7
11
|
export const choice = (arr) => {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
};
|
|
12
|
+
if (!arr || !arr.length) return
|
|
13
|
+
return arr[randomInt(0, arr.length - 1)]
|
|
14
|
+
}
|
|
12
15
|
/**
|
|
13
16
|
* Returns a random sample of size k from a list of items.
|
|
14
17
|
*
|
|
@@ -18,13 +21,12 @@ export const choice = (arr) => {
|
|
|
18
21
|
* @return
|
|
19
22
|
*/
|
|
20
23
|
export function sample(arr, k) {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
return result;
|
|
24
|
+
if (!arr || !arr.length || arr.length < k) return
|
|
25
|
+
const result = []
|
|
26
|
+
for (let i = 0; i < k; i++) {
|
|
27
|
+
result.push(choice(arr))
|
|
28
|
+
}
|
|
29
|
+
return result
|
|
28
30
|
}
|
|
29
31
|
/**
|
|
30
32
|
* Shuffles a collection elements in-place. Uses the Fisher-Yates algorithm for uniform shuffling. If collection is an Object it returns shuffled `Object.values()`.
|
|
@@ -33,16 +35,14 @@ export function sample(arr, k) {
|
|
|
33
35
|
* @return
|
|
34
36
|
*/
|
|
35
37
|
export function shuffle(arr) {
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
const
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
}
|
|
47
|
-
return arr;
|
|
38
|
+
if (!arr || !arr.length) return
|
|
39
|
+
if (isObject(arr)) arr = Object.values(arr)
|
|
40
|
+
const n = arr.length - 1
|
|
41
|
+
for (let i = n; i > 0; i--) {
|
|
42
|
+
const j = randomInt(0, i)
|
|
43
|
+
const temp = arr[j]
|
|
44
|
+
arr[j] = arr[i]
|
|
45
|
+
arr[i] = temp
|
|
46
|
+
}
|
|
47
|
+
return arr
|
|
48
48
|
}
|
package/src/random.ts
CHANGED
|
@@ -1,4 +1,8 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Random
|
|
3
|
+
* @module
|
|
4
|
+
*/
|
|
5
|
+
import { isObject } from './globals'
|
|
2
6
|
|
|
3
7
|
/** Returns a random float between a [min, max) value (max exclusive). */
|
|
4
8
|
export const random = (min = 0, max = 1) => Math.random() * (max - min) + min
|
package/src/strings.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
'use strict'
|
package/src/util.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
'use strict'
|