@cloudglides/nox 1.1.6 → 3.0.0
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 +9 -9
- package/example/package.json +1 -1
- package/example/src/App.css +38 -7
- package/example/src/App.jsx +328 -25
- package/package.json +7 -6
- package/pnpm-workspace.yaml +3 -0
- package/src/core.browser.js +37 -4
- package/src/core.js +37 -4
- package/src/generators/logistic.js +30 -25
- package/src/generators/mixer.js +7 -7
- package/src/generators/mt19937.js +10 -7
- package/src/generators/pcg64.js +23 -12
- package/src/generators/splitmix64.js +12 -6
- package/src/generators/tent.js +12 -7
- package/src/generators/xorshift64.js +6 -3
- package/src/index.browser.js +168 -1
- package/src/index.d.ts +68 -4
- package/src/index.js +169 -1
- package/src/rng.browser.js +5 -6
- package/src/rng.js +95 -94
- package/src/utils/arrays.js +149 -0
- package/src/utils/bits.js +146 -21
- package/src/utils/categorical.js +68 -31
- package/src/utils/clustering.js +143 -0
- package/src/utils/combinatorics.js +113 -69
- package/src/utils/confidence.js +145 -0
- package/src/utils/decomposition.js +204 -0
- package/src/utils/diagnostics.js +309 -0
- package/src/utils/distributions-advanced.js +122 -0
- package/src/utils/distributions-extra.js +102 -11
- package/src/utils/distributions-special.js +77 -20
- package/src/utils/distributions.js +99 -35
- package/src/utils/effects.js +172 -0
- package/src/utils/entropy.browser.js +29 -26
- package/src/utils/entropy.js +18 -8
- package/src/utils/helpers.js +64 -0
- package/src/utils/hypothesis.js +167 -0
- package/src/utils/integration.js +137 -0
- package/src/utils/interpolation.js +221 -0
- package/src/utils/logistic.js +91 -0
- package/src/utils/matrix.js +242 -0
- package/src/utils/noise.js +36 -22
- package/src/utils/odesolvers.js +176 -0
- package/src/utils/optimization.js +215 -0
- package/src/utils/polynomial.js +136 -0
- package/src/utils/precomputed.js +166 -0
- package/src/utils/probability.js +199 -0
- package/src/utils/pvalues.js +142 -0
- package/src/utils/regression.js +170 -0
- package/src/utils/resampling.js +112 -0
- package/src/utils/rootfinding.js +158 -0
- package/src/utils/sampling.js +86 -77
- package/src/utils/seed.js +10 -4
- package/src/utils/seeding.js +24 -12
- package/src/utils/sequence.js +116 -32
- package/src/utils/state.js +48 -36
- package/src/utils/statistics.js +64 -2
- package/src/utils/stochastic.js +91 -31
- package/src/utils/stratified.js +108 -0
- package/src/utils/timeseries.js +166 -0
- package/src/utils/transforms.js +146 -0
- package/test/comprehensive.js +4 -3
- package/test/new-features.js +52 -0
- package/IMPROVEMENTS.md +0 -58
- package/PERFORMANCE.md +0 -69
- package/example/pnpm-lock.yaml +0 -1006
package/src/index.js
CHANGED
|
@@ -6,9 +6,15 @@ export {
|
|
|
6
6
|
exponential,
|
|
7
7
|
uniform,
|
|
8
8
|
poisson,
|
|
9
|
+
normals,
|
|
10
|
+
exponentials,
|
|
9
11
|
shuffle,
|
|
10
12
|
pick,
|
|
11
13
|
sample,
|
|
14
|
+
sampleWithReplacement,
|
|
15
|
+
permute,
|
|
16
|
+
range,
|
|
17
|
+
cycle,
|
|
12
18
|
saveState,
|
|
13
19
|
restoreState,
|
|
14
20
|
cloneGenerator,
|
|
@@ -17,7 +23,168 @@ export {
|
|
|
17
23
|
reservoirSample,
|
|
18
24
|
meanTest,
|
|
19
25
|
varianceTest,
|
|
20
|
-
kolmogorovSmirnovTest
|
|
26
|
+
kolmogorovSmirnovTest,
|
|
27
|
+
skewness,
|
|
28
|
+
kurtosis,
|
|
29
|
+
median,
|
|
30
|
+
quantile,
|
|
31
|
+
beta,
|
|
32
|
+
gamma,
|
|
33
|
+
chi2,
|
|
34
|
+
binomial,
|
|
35
|
+
geometric,
|
|
36
|
+
weibull,
|
|
37
|
+
lognormal,
|
|
38
|
+
rayleigh,
|
|
39
|
+
cauchy,
|
|
40
|
+
dirichlet,
|
|
41
|
+
dirichlets,
|
|
42
|
+
mixture,
|
|
43
|
+
mixtures,
|
|
44
|
+
studentT,
|
|
45
|
+
studentTs,
|
|
46
|
+
betaBinomial,
|
|
47
|
+
brownianMotion,
|
|
48
|
+
ornsteinUhlenbeck,
|
|
49
|
+
geometricBrownian,
|
|
50
|
+
categorical,
|
|
51
|
+
multinomial,
|
|
52
|
+
categorical2D,
|
|
53
|
+
perlin2D,
|
|
54
|
+
valueNoise,
|
|
55
|
+
combinations,
|
|
56
|
+
permutations,
|
|
57
|
+
kPermutations,
|
|
58
|
+
randomCombination,
|
|
59
|
+
randomPermutation,
|
|
60
|
+
rotateBits,
|
|
61
|
+
extractBits,
|
|
62
|
+
hammingWeight,
|
|
63
|
+
bitRange,
|
|
64
|
+
popcountNum,
|
|
65
|
+
clz,
|
|
66
|
+
ctz,
|
|
67
|
+
reverseBits,
|
|
68
|
+
setBit,
|
|
69
|
+
clearBit,
|
|
70
|
+
toggleBit,
|
|
71
|
+
SeedSequence,
|
|
72
|
+
seedMultiple,
|
|
73
|
+
seedFromTime,
|
|
74
|
+
seedFromEntropy,
|
|
75
|
+
repeat,
|
|
76
|
+
until,
|
|
77
|
+
times,
|
|
78
|
+
chiSquareTest,
|
|
79
|
+
entropy,
|
|
80
|
+
autocorrelation,
|
|
81
|
+
runTest,
|
|
82
|
+
clearCryptoCache,
|
|
83
|
+
combined,
|
|
84
|
+
bootstrap,
|
|
85
|
+
jackknife,
|
|
86
|
+
crossValidation,
|
|
87
|
+
permutationTest,
|
|
88
|
+
stratifiedSample,
|
|
89
|
+
stratifiedSampleProportional,
|
|
90
|
+
stratify,
|
|
91
|
+
cdf,
|
|
92
|
+
ppf,
|
|
93
|
+
sf,
|
|
94
|
+
WeightedDistribution,
|
|
95
|
+
CategoricalDistribution,
|
|
96
|
+
NormalDistribution,
|
|
97
|
+
bootstrapCI,
|
|
98
|
+
meanCI,
|
|
99
|
+
proportionCI,
|
|
100
|
+
cohensD,
|
|
101
|
+
hedgesG,
|
|
102
|
+
correlation,
|
|
103
|
+
cramersV,
|
|
104
|
+
etaSquared,
|
|
105
|
+
glasssDelta,
|
|
106
|
+
sum,
|
|
107
|
+
mean,
|
|
108
|
+
min,
|
|
109
|
+
max,
|
|
110
|
+
unique,
|
|
111
|
+
chunk,
|
|
112
|
+
flatten,
|
|
113
|
+
zip,
|
|
114
|
+
transpose,
|
|
115
|
+
partition,
|
|
116
|
+
tTest,
|
|
117
|
+
welchTTest,
|
|
118
|
+
mannWhitneyU,
|
|
119
|
+
oneWayAnova,
|
|
120
|
+
zscore,
|
|
121
|
+
standardize,
|
|
122
|
+
minMaxScale,
|
|
123
|
+
logTransform,
|
|
124
|
+
sqrtTransform,
|
|
125
|
+
rank,
|
|
126
|
+
robustScale,
|
|
127
|
+
LinearRegression,
|
|
128
|
+
MultipleRegression,
|
|
129
|
+
diff,
|
|
130
|
+
lag,
|
|
131
|
+
shift,
|
|
132
|
+
sma,
|
|
133
|
+
ema,
|
|
134
|
+
acf,
|
|
135
|
+
pacf,
|
|
136
|
+
matrixAdd,
|
|
137
|
+
matrixSub,
|
|
138
|
+
matrixMul,
|
|
139
|
+
elementwiseMul,
|
|
140
|
+
scalarMul,
|
|
141
|
+
determinant,
|
|
142
|
+
trace,
|
|
143
|
+
norm,
|
|
144
|
+
inverse as matrixInverse,
|
|
145
|
+
trapezoidal,
|
|
146
|
+
simpsons,
|
|
147
|
+
adaptiveSimpson,
|
|
148
|
+
gaussQuadrature,
|
|
149
|
+
numericalDerivative,
|
|
150
|
+
numericalSecondDerivative,
|
|
151
|
+
LinearInterpolator,
|
|
152
|
+
CubicSplineInterpolator,
|
|
153
|
+
lagrangeInterpolation,
|
|
154
|
+
polynomialFit,
|
|
155
|
+
bisection,
|
|
156
|
+
newtonRaphson,
|
|
157
|
+
secant,
|
|
158
|
+
falsePosition,
|
|
159
|
+
fixedPoint,
|
|
160
|
+
eulerMethod,
|
|
161
|
+
rk4,
|
|
162
|
+
systemEuler,
|
|
163
|
+
systemRK4,
|
|
164
|
+
rk45Adaptive,
|
|
165
|
+
svd,
|
|
166
|
+
qr,
|
|
167
|
+
cholesky,
|
|
168
|
+
lu,
|
|
169
|
+
gradientDescent,
|
|
170
|
+
momentumDescent,
|
|
171
|
+
adam,
|
|
172
|
+
simplex,
|
|
173
|
+
brent,
|
|
174
|
+
tTestPValue,
|
|
175
|
+
zTestPValue,
|
|
176
|
+
fTestPValue,
|
|
177
|
+
chi2PValue,
|
|
178
|
+
uTestPValue,
|
|
179
|
+
pearsonPValue,
|
|
180
|
+
residualDiagnostics,
|
|
181
|
+
leverageValues,
|
|
182
|
+
cookDistance,
|
|
183
|
+
durwinWatson,
|
|
184
|
+
vif,
|
|
185
|
+
LogisticRegression,
|
|
186
|
+
PolynomialRegression,
|
|
187
|
+
KMeans
|
|
21
188
|
} from './core.js';
|
|
22
189
|
|
|
23
190
|
export {
|
|
@@ -29,3 +196,4 @@ export {
|
|
|
29
196
|
Tent,
|
|
30
197
|
Mixer
|
|
31
198
|
} from './generators/index.js';
|
|
199
|
+
|
package/src/rng.browser.js
CHANGED
|
@@ -36,8 +36,7 @@ export class RNG {
|
|
|
36
36
|
}
|
|
37
37
|
if (min > max) [min, max] = [max, min];
|
|
38
38
|
const range = max - min + 1;
|
|
39
|
-
|
|
40
|
-
return val + min;
|
|
39
|
+
return min + this.nextInt(range);
|
|
41
40
|
}
|
|
42
41
|
|
|
43
42
|
bool(probability = 0.5) {
|
|
@@ -55,13 +54,13 @@ export class RNG {
|
|
|
55
54
|
throw new TypeError('min, max, and step must be numbers');
|
|
56
55
|
}
|
|
57
56
|
if (!Number.isInteger(min) || !Number.isInteger(max) || !Number.isInteger(step)) {
|
|
58
|
-
throw new
|
|
57
|
+
throw new TypeError('min, max, and step must be integers');
|
|
59
58
|
}
|
|
60
59
|
if (step <= 0) {
|
|
61
|
-
throw new
|
|
60
|
+
throw new RangeError('step must be positive');
|
|
62
61
|
}
|
|
63
62
|
if (min > max) {
|
|
64
|
-
throw new
|
|
63
|
+
throw new RangeError('min must be less than or equal to max');
|
|
65
64
|
}
|
|
66
65
|
|
|
67
66
|
const count = Math.floor((max - min) / step) + 1;
|
|
@@ -75,7 +74,7 @@ export class RNG {
|
|
|
75
74
|
}
|
|
76
75
|
const len = arr.length;
|
|
77
76
|
if (len === 0) {
|
|
78
|
-
throw new
|
|
77
|
+
throw new RangeError('choice() requires non-empty array');
|
|
79
78
|
}
|
|
80
79
|
return arr[this.nextInt(len)];
|
|
81
80
|
}
|
package/src/rng.js
CHANGED
|
@@ -28,17 +28,16 @@ export class RNG {
|
|
|
28
28
|
}
|
|
29
29
|
|
|
30
30
|
int(min, max) {
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
}
|
|
31
|
+
if (typeof min !== 'number' || typeof max !== 'number') {
|
|
32
|
+
throw new TypeError('int() requires two number arguments');
|
|
33
|
+
}
|
|
34
|
+
if (!Number.isInteger(min) || !Number.isInteger(max)) {
|
|
35
|
+
throw new TypeError('int() arguments must be integers');
|
|
36
|
+
}
|
|
37
|
+
if (min > max) [min, max] = [max, min];
|
|
38
|
+
const range = max - min + 1;
|
|
39
|
+
return min + this.nextInt(range);
|
|
40
|
+
}
|
|
42
41
|
|
|
43
42
|
bool(probability = 0.5) {
|
|
44
43
|
if (typeof probability !== 'number') {
|
|
@@ -55,13 +54,13 @@ export class RNG {
|
|
|
55
54
|
throw new TypeError('min, max, and step must be numbers');
|
|
56
55
|
}
|
|
57
56
|
if (!Number.isInteger(min) || !Number.isInteger(max) || !Number.isInteger(step)) {
|
|
58
|
-
throw new
|
|
57
|
+
throw new TypeError('min, max, and step must be integers');
|
|
59
58
|
}
|
|
60
59
|
if (step <= 0) {
|
|
61
|
-
throw new
|
|
60
|
+
throw new RangeError('step must be positive');
|
|
62
61
|
}
|
|
63
62
|
if (min > max) {
|
|
64
|
-
throw new
|
|
63
|
+
throw new RangeError('min must be less than or equal to max');
|
|
65
64
|
}
|
|
66
65
|
|
|
67
66
|
const count = Math.floor((max - min) / step) + 1;
|
|
@@ -70,91 +69,93 @@ export class RNG {
|
|
|
70
69
|
}
|
|
71
70
|
|
|
72
71
|
choice(arr) {
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
72
|
+
if (!Array.isArray(arr)) {
|
|
73
|
+
throw new TypeError('choice() requires array');
|
|
74
|
+
}
|
|
75
|
+
const len = arr.length;
|
|
76
|
+
if (len === 0) {
|
|
77
|
+
throw new RangeError('choice() requires non-empty array');
|
|
78
|
+
}
|
|
79
|
+
return arr[this.nextInt(len)];
|
|
80
|
+
}
|
|
82
81
|
|
|
83
82
|
batch(count, fn) {
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
83
|
+
if (typeof count !== 'number' || !Number.isInteger(count)) {
|
|
84
|
+
throw new TypeError('count must be an integer');
|
|
85
|
+
}
|
|
86
|
+
if (count < 0) {
|
|
87
|
+
throw new RangeError('count must be non-negative');
|
|
88
|
+
}
|
|
89
|
+
if (count === 0) {
|
|
90
|
+
return [];
|
|
91
|
+
}
|
|
92
|
+
if (typeof fn !== 'function') {
|
|
93
|
+
throw new TypeError('fn must be a function');
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
const result = new Array(count);
|
|
97
|
+
for (let i = 0; i < count; i++) {
|
|
98
|
+
result[i] = fn(this, i);
|
|
99
|
+
}
|
|
100
|
+
return result;
|
|
101
|
+
}
|
|
103
102
|
|
|
104
103
|
floats(count) {
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
104
|
+
if (typeof count !== 'number' || !Number.isInteger(count)) {
|
|
105
|
+
throw new TypeError('count must be an integer');
|
|
106
|
+
}
|
|
107
|
+
if (count < 0) {
|
|
108
|
+
throw new RangeError('count must be non-negative');
|
|
109
|
+
}
|
|
110
|
+
if (count === 0) {
|
|
111
|
+
return [];
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
const result = new Array(count);
|
|
115
|
+
for (let i = 0; i < count; i++) {
|
|
116
|
+
result[i] = this.nextFloat();
|
|
117
|
+
}
|
|
118
|
+
return result;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
ints(count, max = 2147483647) {
|
|
122
|
+
if (typeof count !== 'number' || !Number.isInteger(count)) {
|
|
123
|
+
throw new TypeError('count must be an integer');
|
|
124
|
+
}
|
|
125
|
+
if (count < 0) {
|
|
126
|
+
throw new RangeError('count must be non-negative');
|
|
127
|
+
}
|
|
128
|
+
if (count === 0) {
|
|
129
|
+
return [];
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
const result = new Array(count);
|
|
133
|
+
for (let i = 0; i < count; i++) {
|
|
134
|
+
result[i] = this.nextInt(max);
|
|
135
|
+
}
|
|
136
|
+
return result;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
bools(count, probability = 0.5) {
|
|
140
|
+
if (typeof count !== 'number' || !Number.isInteger(count)) {
|
|
141
|
+
throw new TypeError('count must be an integer');
|
|
142
|
+
}
|
|
143
|
+
if (count < 0) {
|
|
144
|
+
throw new RangeError('count must be non-negative');
|
|
145
|
+
}
|
|
146
|
+
if (count === 0) {
|
|
147
|
+
return [];
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
const result = new Array(count);
|
|
151
|
+
for (let i = 0; i < count; i++) {
|
|
152
|
+
result[i] = this.bool(probability);
|
|
153
|
+
}
|
|
154
|
+
return result;
|
|
155
|
+
}
|
|
157
156
|
}
|
|
158
157
|
|
|
159
158
|
export const rng = () => new RNG();
|
|
160
159
|
|
|
160
|
+
|
|
161
|
+
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
export function sum(arr) {
|
|
2
|
+
if (!Array.isArray(arr)) {
|
|
3
|
+
throw new TypeError('arr must be array');
|
|
4
|
+
}
|
|
5
|
+
let total = 0;
|
|
6
|
+
for (let i = 0; i < arr.length; i++) {
|
|
7
|
+
total += arr[i];
|
|
8
|
+
}
|
|
9
|
+
return total;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export function mean(arr) {
|
|
13
|
+
if (!Array.isArray(arr) || arr.length === 0) {
|
|
14
|
+
throw new TypeError('arr must be non-empty array');
|
|
15
|
+
}
|
|
16
|
+
return sum(arr) / arr.length;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export function min(arr) {
|
|
20
|
+
if (!Array.isArray(arr) || arr.length === 0) {
|
|
21
|
+
throw new TypeError('arr must be non-empty array');
|
|
22
|
+
}
|
|
23
|
+
let minVal = arr[0];
|
|
24
|
+
for (let i = 1; i < arr.length; i++) {
|
|
25
|
+
if (arr[i] < minVal) minVal = arr[i];
|
|
26
|
+
}
|
|
27
|
+
return minVal;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export function max(arr) {
|
|
31
|
+
if (!Array.isArray(arr) || arr.length === 0) {
|
|
32
|
+
throw new TypeError('arr must be non-empty array');
|
|
33
|
+
}
|
|
34
|
+
let maxVal = arr[0];
|
|
35
|
+
for (let i = 1; i < arr.length; i++) {
|
|
36
|
+
if (arr[i] > maxVal) maxVal = arr[i];
|
|
37
|
+
}
|
|
38
|
+
return maxVal;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export function unique(arr) {
|
|
42
|
+
if (!Array.isArray(arr)) {
|
|
43
|
+
throw new TypeError('arr must be array');
|
|
44
|
+
}
|
|
45
|
+
const seen = new Set();
|
|
46
|
+
const result = [];
|
|
47
|
+
for (let i = 0; i < arr.length; i++) {
|
|
48
|
+
if (!seen.has(arr[i])) {
|
|
49
|
+
seen.add(arr[i]);
|
|
50
|
+
result.push(arr[i]);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return result;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export function chunk(arr, size) {
|
|
57
|
+
if (!Array.isArray(arr)) {
|
|
58
|
+
throw new TypeError('arr must be array');
|
|
59
|
+
}
|
|
60
|
+
if (typeof size !== 'number' || size < 1) {
|
|
61
|
+
throw new RangeError('size must be positive integer');
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const result = [];
|
|
65
|
+
for (let i = 0; i < arr.length; i += size) {
|
|
66
|
+
result.push(arr.slice(i, i + size));
|
|
67
|
+
}
|
|
68
|
+
return result;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export function flatten(arr, depth = Infinity) {
|
|
72
|
+
if (!Array.isArray(arr)) {
|
|
73
|
+
throw new TypeError('arr must be array');
|
|
74
|
+
}
|
|
75
|
+
if (typeof depth !== 'number' || depth < 0) {
|
|
76
|
+
throw new RangeError('depth must be non-negative number');
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
if (depth === 0) return arr;
|
|
80
|
+
|
|
81
|
+
const result = [];
|
|
82
|
+
for (let i = 0; i < arr.length; i++) {
|
|
83
|
+
if (Array.isArray(arr[i]) && depth > 0) {
|
|
84
|
+
result.push(...flatten(arr[i], depth - 1));
|
|
85
|
+
} else {
|
|
86
|
+
result.push(arr[i]);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
return result;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
export function zip(...arrays) {
|
|
93
|
+
if (arrays.length === 0) {
|
|
94
|
+
throw new TypeError('at least one array required');
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
for (let i = 0; i < arrays.length; i++) {
|
|
98
|
+
if (!Array.isArray(arrays[i])) {
|
|
99
|
+
throw new TypeError(`argument ${i} must be array`);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
const minLen = Math.min(...arrays.map(a => a.length));
|
|
104
|
+
const result = new Array(minLen);
|
|
105
|
+
|
|
106
|
+
for (let i = 0; i < minLen; i++) {
|
|
107
|
+
result[i] = arrays.map(a => a[i]);
|
|
108
|
+
}
|
|
109
|
+
return result;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
export function transpose(matrix) {
|
|
113
|
+
if (!Array.isArray(matrix) || matrix.length === 0) {
|
|
114
|
+
throw new TypeError('matrix must be non-empty 2D array');
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
const cols = matrix[0].length;
|
|
118
|
+
const result = new Array(cols);
|
|
119
|
+
|
|
120
|
+
for (let j = 0; j < cols; j++) {
|
|
121
|
+
result[j] = new Array(matrix.length);
|
|
122
|
+
for (let i = 0; i < matrix.length; i++) {
|
|
123
|
+
result[j][i] = matrix[i][j];
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
return result;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
export function partition(arr, predicate) {
|
|
130
|
+
if (!Array.isArray(arr)) {
|
|
131
|
+
throw new TypeError('arr must be array');
|
|
132
|
+
}
|
|
133
|
+
if (typeof predicate !== 'function') {
|
|
134
|
+
throw new TypeError('predicate must be function');
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
const truthy = [];
|
|
138
|
+
const falsy = [];
|
|
139
|
+
|
|
140
|
+
for (let i = 0; i < arr.length; i++) {
|
|
141
|
+
if (predicate(arr[i], i)) {
|
|
142
|
+
truthy.push(arr[i]);
|
|
143
|
+
} else {
|
|
144
|
+
falsy.push(arr[i]);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
return [truthy, falsy];
|
|
149
|
+
}
|