@naturalcycles/js-lib 14.224.0 → 14.226.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/dist/array/array.util.d.ts +31 -27
- package/dist/array/array.util.js +45 -20
- package/dist-esm/array/array.util.js +43 -19
- package/package.json +1 -1
- package/src/array/array.util.ts +70 -41
|
@@ -103,26 +103,30 @@ export declare function _sortBy<T>(items: T[], mapper: Mapper<T, any>, mutate?:
|
|
|
103
103
|
*/
|
|
104
104
|
export declare function _sortDescBy<T>(items: T[], mapper: Mapper<T, any>, mutate?: boolean): T[];
|
|
105
105
|
/**
|
|
106
|
-
*
|
|
106
|
+
* Similar to `Array.find`, but the `predicate` may return `END` to stop the iteration early.
|
|
107
107
|
*
|
|
108
|
-
*
|
|
109
|
-
* iOS Safari only has it since 15.4
|
|
108
|
+
* Use `Array.find` if you don't need to stop the iteration early.
|
|
110
109
|
*/
|
|
111
|
-
export declare function
|
|
112
|
-
export declare function _takeWhile<T>(items: T[], predicate: Predicate<T>): T[];
|
|
113
|
-
export declare function _takeRightWhile<T>(items: T[], predicate: Predicate<T>): T[];
|
|
114
|
-
export declare function _dropWhile<T>(items: T[], predicate: Predicate<T>): T[];
|
|
115
|
-
export declare function _dropRightWhile<T>(items: T[], predicate: Predicate<T>): T[];
|
|
110
|
+
export declare function _find<T>(items: readonly T[], predicate: AbortablePredicate<T>): T | undefined;
|
|
116
111
|
/**
|
|
117
|
-
*
|
|
112
|
+
* Similar to `Array.findLast`, but the `predicate` may return `END` to stop the iteration early.
|
|
118
113
|
*
|
|
119
|
-
* `
|
|
114
|
+
* Use `Array.findLast` if you don't need to stop the iteration early, which is supported:
|
|
115
|
+
* - in Node since 18+
|
|
116
|
+
* - in iOS Safari since 15.4
|
|
120
117
|
*/
|
|
121
|
-
export declare function
|
|
118
|
+
export declare function _findLast<T>(items: readonly T[], predicate: AbortablePredicate<T>): T | undefined;
|
|
119
|
+
export declare function _takeWhile<T>(items: readonly T[], predicate: Predicate<T>): T[];
|
|
120
|
+
export declare function _takeRightWhile<T>(items: readonly T[], predicate: Predicate<T>): T[];
|
|
121
|
+
export declare function _dropWhile<T>(items: readonly T[], predicate: Predicate<T>): T[];
|
|
122
|
+
export declare function _dropRightWhile<T>(items: readonly T[], predicate: Predicate<T>): T[];
|
|
122
123
|
/**
|
|
124
|
+
* Counts how many items match the predicate.
|
|
125
|
+
*
|
|
123
126
|
* `limit` allows to exit early when limit count is reached, skipping further iterations (perf optimization).
|
|
124
127
|
*/
|
|
125
|
-
export declare function
|
|
128
|
+
export declare function _count<T>(items: Iterable<T>, predicate: AbortablePredicate<T>, limit?: number): number;
|
|
129
|
+
export declare function _countBy<T>(items: Iterable<T>, mapper: Mapper<T, any>): StringMap<number>;
|
|
126
130
|
/**
|
|
127
131
|
* Returns an intersection between 2 arrays.
|
|
128
132
|
*
|
|
@@ -153,8 +157,8 @@ export declare function _difference<T>(source: T[], ...diffs: T[][]): T[];
|
|
|
153
157
|
/**
|
|
154
158
|
* Returns the sum of items, or 0 for empty array.
|
|
155
159
|
*/
|
|
156
|
-
export declare function _sum(items: number
|
|
157
|
-
export declare function _sumBy<T>(items: T
|
|
160
|
+
export declare function _sum(items: Iterable<number>): number;
|
|
161
|
+
export declare function _sumBy<T>(items: Iterable<T>, mapper: Mapper<T, number | undefined>): number;
|
|
158
162
|
/**
|
|
159
163
|
* Map an array of T to a StringMap<V>,
|
|
160
164
|
* by returning a tuple of [key, value] from a mapper function.
|
|
@@ -168,7 +172,7 @@ export declare function _sumBy<T>(items: T[], mapper: Mapper<T, number | undefin
|
|
|
168
172
|
* _mapToObject([1, 2, 3], n => [n, `id${n}`])
|
|
169
173
|
* // { '1': 'id1, '2': 'id2', '3': 'id3' }
|
|
170
174
|
*/
|
|
171
|
-
export declare function _mapToObject<T, V>(array: T
|
|
175
|
+
export declare function _mapToObject<T, V>(array: Iterable<T>, mapper: (item: T) => [key: any, value: V] | FalsyValue): StringMap<V>;
|
|
172
176
|
/**
|
|
173
177
|
* Randomly shuffle an array values.
|
|
174
178
|
* Fisher–Yates algorithm.
|
|
@@ -179,28 +183,28 @@ export declare function _shuffle<T>(array: T[], mutate?: boolean): T[];
|
|
|
179
183
|
* Returns last item of non-empty array.
|
|
180
184
|
* Throws if array is empty.
|
|
181
185
|
*/
|
|
182
|
-
export declare function _last<T>(array: T[]): T;
|
|
186
|
+
export declare function _last<T>(array: readonly T[]): T;
|
|
183
187
|
/**
|
|
184
188
|
* Returns last item of the array (or undefined if array is empty).
|
|
185
189
|
*/
|
|
186
|
-
export declare function _lastOrUndefined<T>(array: T[]): T | undefined;
|
|
190
|
+
export declare function _lastOrUndefined<T>(array: readonly T[]): T | undefined;
|
|
187
191
|
/**
|
|
188
192
|
* Returns the first item of non-empty array.
|
|
189
193
|
* Throws if array is empty.
|
|
190
194
|
*/
|
|
191
|
-
export declare function _first<T>(array: T[]): T;
|
|
192
|
-
export declare function _minOrUndefined<T>(array: T[]): NonNullable<T> | undefined;
|
|
195
|
+
export declare function _first<T>(array: readonly T[]): T;
|
|
196
|
+
export declare function _minOrUndefined<T>(array: readonly T[]): NonNullable<T> | undefined;
|
|
193
197
|
/**
|
|
194
198
|
* Filters out nullish values (undefined and null).
|
|
195
199
|
*/
|
|
196
|
-
export declare function _min<T>(array: T[]): NonNullable<T>;
|
|
197
|
-
export declare function _maxOrUndefined<T>(array: T[]): NonNullable<T> | undefined;
|
|
200
|
+
export declare function _min<T>(array: readonly T[]): NonNullable<T>;
|
|
201
|
+
export declare function _maxOrUndefined<T>(array: readonly T[]): NonNullable<T> | undefined;
|
|
198
202
|
/**
|
|
199
203
|
* Filters out nullish values (undefined and null).
|
|
200
204
|
*/
|
|
201
|
-
export declare function _max<T>(array: T[]): NonNullable<T>;
|
|
202
|
-
export declare function _maxBy<T>(array: T[], mapper: Mapper<T, number | string | undefined>): T;
|
|
203
|
-
export declare function _minBy<T>(array: T[], mapper: Mapper<T, number | string | undefined>): T;
|
|
204
|
-
export declare function _maxByOrUndefined<T>(array: T[], mapper: Mapper<T, number | string | undefined>): T | undefined;
|
|
205
|
-
export declare function _minByOrUndefined<T>(array: T[], mapper: Mapper<T, number | string | undefined>): T | undefined;
|
|
206
|
-
export declare function _zip<T1, T2>(array1: T1[], array2: T2[]): [T1, T2][];
|
|
205
|
+
export declare function _max<T>(array: readonly T[]): NonNullable<T>;
|
|
206
|
+
export declare function _maxBy<T>(array: readonly T[], mapper: Mapper<T, number | string | undefined>): T;
|
|
207
|
+
export declare function _minBy<T>(array: readonly T[], mapper: Mapper<T, number | string | undefined>): T;
|
|
208
|
+
export declare function _maxByOrUndefined<T>(array: readonly T[], mapper: Mapper<T, number | string | undefined>): T | undefined;
|
|
209
|
+
export declare function _minByOrUndefined<T>(array: readonly T[], mapper: Mapper<T, number | string | undefined>): T | undefined;
|
|
210
|
+
export declare function _zip<T1, T2>(array1: readonly T1[], array2: readonly T2[]): [T1, T2][];
|
package/dist/array/array.util.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports._zip = exports._minByOrUndefined = exports._maxByOrUndefined = exports._minBy = exports._maxBy = exports._max = exports._maxOrUndefined = exports._min = exports._minOrUndefined = exports._first = exports._lastOrUndefined = exports._last = exports._shuffle = exports._mapToObject = exports._sumBy = exports._sum = exports._difference = exports._intersectsWith = exports._intersection = exports._countBy = exports._count = exports._dropRightWhile = exports._dropWhile = exports._takeRightWhile = exports._takeWhile = exports._findLast = exports._sortDescBy = exports._sortBy = exports._groupBy = exports._mapBy = exports._by = exports._uniqBy = exports._pushUniqBy = exports._pushUniq = exports._uniq = exports._chunk = void 0;
|
|
3
|
+
exports._zip = exports._minByOrUndefined = exports._maxByOrUndefined = exports._minBy = exports._maxBy = exports._max = exports._maxOrUndefined = exports._min = exports._minOrUndefined = exports._first = exports._lastOrUndefined = exports._last = exports._shuffle = exports._mapToObject = exports._sumBy = exports._sum = exports._difference = exports._intersectsWith = exports._intersection = exports._countBy = exports._count = exports._dropRightWhile = exports._dropWhile = exports._takeRightWhile = exports._takeWhile = exports._findLast = exports._find = exports._sortDescBy = exports._sortBy = exports._groupBy = exports._mapBy = exports._by = exports._uniqBy = exports._pushUniqBy = exports._pushUniq = exports._uniq = exports._chunk = void 0;
|
|
4
4
|
const is_util_1 = require("../is.util");
|
|
5
5
|
const types_1 = require("../types");
|
|
6
6
|
/**
|
|
@@ -172,13 +172,29 @@ function _sortDescBy(items, mapper, mutate = false) {
|
|
|
172
172
|
}
|
|
173
173
|
exports._sortDescBy = _sortDescBy;
|
|
174
174
|
/**
|
|
175
|
-
*
|
|
175
|
+
* Similar to `Array.find`, but the `predicate` may return `END` to stop the iteration early.
|
|
176
176
|
*
|
|
177
|
-
*
|
|
178
|
-
|
|
177
|
+
* Use `Array.find` if you don't need to stop the iteration early.
|
|
178
|
+
*/
|
|
179
|
+
function _find(items, predicate) {
|
|
180
|
+
for (const [i, item] of items.entries()) {
|
|
181
|
+
const result = predicate(item, i);
|
|
182
|
+
if (result === types_1.END)
|
|
183
|
+
return;
|
|
184
|
+
if (result)
|
|
185
|
+
return item;
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
exports._find = _find;
|
|
189
|
+
/**
|
|
190
|
+
* Similar to `Array.findLast`, but the `predicate` may return `END` to stop the iteration early.
|
|
191
|
+
*
|
|
192
|
+
* Use `Array.findLast` if you don't need to stop the iteration early, which is supported:
|
|
193
|
+
* - in Node since 18+
|
|
194
|
+
* - in iOS Safari since 15.4
|
|
179
195
|
*/
|
|
180
196
|
function _findLast(items, predicate) {
|
|
181
|
-
return
|
|
197
|
+
return _find(items.slice().reverse(), predicate);
|
|
182
198
|
}
|
|
183
199
|
exports._findLast = _findLast;
|
|
184
200
|
function _takeWhile(items, predicate) {
|
|
@@ -213,8 +229,9 @@ function _count(items, predicate, limit) {
|
|
|
213
229
|
if (limit === 0)
|
|
214
230
|
return 0;
|
|
215
231
|
let count = 0;
|
|
216
|
-
|
|
217
|
-
|
|
232
|
+
let i = 0;
|
|
233
|
+
for (const item of items) {
|
|
234
|
+
const r = predicate(item, i++);
|
|
218
235
|
if (r === types_1.END)
|
|
219
236
|
break;
|
|
220
237
|
if (r) {
|
|
@@ -226,15 +243,13 @@ function _count(items, predicate, limit) {
|
|
|
226
243
|
return count;
|
|
227
244
|
}
|
|
228
245
|
exports._count = _count;
|
|
229
|
-
/**
|
|
230
|
-
* `limit` allows to exit early when limit count is reached, skipping further iterations (perf optimization).
|
|
231
|
-
*/
|
|
232
246
|
function _countBy(items, mapper) {
|
|
233
247
|
const map = {};
|
|
234
|
-
|
|
235
|
-
|
|
248
|
+
let i = 0;
|
|
249
|
+
for (const item of items) {
|
|
250
|
+
const key = mapper(item, i++);
|
|
236
251
|
map[key] = (map[key] || 0) + 1;
|
|
237
|
-
}
|
|
252
|
+
}
|
|
238
253
|
return map;
|
|
239
254
|
}
|
|
240
255
|
exports._countBy = _countBy;
|
|
@@ -281,14 +296,24 @@ exports._difference = _difference;
|
|
|
281
296
|
* Returns the sum of items, or 0 for empty array.
|
|
282
297
|
*/
|
|
283
298
|
function _sum(items) {
|
|
284
|
-
|
|
299
|
+
let sum = 0;
|
|
300
|
+
for (const n of items) {
|
|
301
|
+
sum += n;
|
|
302
|
+
}
|
|
303
|
+
return sum;
|
|
285
304
|
}
|
|
286
305
|
exports._sum = _sum;
|
|
287
306
|
function _sumBy(items, mapper) {
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
307
|
+
let sum = 0;
|
|
308
|
+
let i = 0;
|
|
309
|
+
for (const n of items) {
|
|
310
|
+
const v = mapper(n, i++);
|
|
311
|
+
if (typeof v === 'number') {
|
|
312
|
+
// count only numbers, nothing else
|
|
313
|
+
sum += v;
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
return sum;
|
|
292
317
|
}
|
|
293
318
|
exports._sumBy = _sumBy;
|
|
294
319
|
/**
|
|
@@ -360,7 +385,7 @@ function _minOrUndefined(array) {
|
|
|
360
385
|
const a = array.filter(is_util_1._isNotNullish);
|
|
361
386
|
if (!a.length)
|
|
362
387
|
return;
|
|
363
|
-
return
|
|
388
|
+
return a.reduce((min, item) => (min <= item ? min : item));
|
|
364
389
|
}
|
|
365
390
|
exports._minOrUndefined = _minOrUndefined;
|
|
366
391
|
/**
|
|
@@ -377,7 +402,7 @@ function _maxOrUndefined(array) {
|
|
|
377
402
|
const a = array.filter(is_util_1._isNotNullish);
|
|
378
403
|
if (!a.length)
|
|
379
404
|
return;
|
|
380
|
-
return
|
|
405
|
+
return a.reduce((max, item) => (max >= item ? max : item));
|
|
381
406
|
}
|
|
382
407
|
exports._maxOrUndefined = _maxOrUndefined;
|
|
383
408
|
/**
|
|
@@ -159,13 +159,28 @@ export function _sortDescBy(items, mapper, mutate = false) {
|
|
|
159
159
|
return _sortBy(items, mapper, mutate, 'desc');
|
|
160
160
|
}
|
|
161
161
|
/**
|
|
162
|
-
*
|
|
162
|
+
* Similar to `Array.find`, but the `predicate` may return `END` to stop the iteration early.
|
|
163
163
|
*
|
|
164
|
-
*
|
|
165
|
-
|
|
164
|
+
* Use `Array.find` if you don't need to stop the iteration early.
|
|
165
|
+
*/
|
|
166
|
+
export function _find(items, predicate) {
|
|
167
|
+
for (const [i, item] of items.entries()) {
|
|
168
|
+
const result = predicate(item, i);
|
|
169
|
+
if (result === END)
|
|
170
|
+
return;
|
|
171
|
+
if (result)
|
|
172
|
+
return item;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Similar to `Array.findLast`, but the `predicate` may return `END` to stop the iteration early.
|
|
177
|
+
*
|
|
178
|
+
* Use `Array.findLast` if you don't need to stop the iteration early, which is supported:
|
|
179
|
+
* - in Node since 18+
|
|
180
|
+
* - in iOS Safari since 15.4
|
|
166
181
|
*/
|
|
167
182
|
export function _findLast(items, predicate) {
|
|
168
|
-
return
|
|
183
|
+
return _find(items.slice().reverse(), predicate);
|
|
169
184
|
}
|
|
170
185
|
export function _takeWhile(items, predicate) {
|
|
171
186
|
let proceed = true;
|
|
@@ -195,8 +210,9 @@ export function _count(items, predicate, limit) {
|
|
|
195
210
|
if (limit === 0)
|
|
196
211
|
return 0;
|
|
197
212
|
let count = 0;
|
|
198
|
-
|
|
199
|
-
|
|
213
|
+
let i = 0;
|
|
214
|
+
for (const item of items) {
|
|
215
|
+
const r = predicate(item, i++);
|
|
200
216
|
if (r === END)
|
|
201
217
|
break;
|
|
202
218
|
if (r) {
|
|
@@ -207,15 +223,13 @@ export function _count(items, predicate, limit) {
|
|
|
207
223
|
}
|
|
208
224
|
return count;
|
|
209
225
|
}
|
|
210
|
-
/**
|
|
211
|
-
* `limit` allows to exit early when limit count is reached, skipping further iterations (perf optimization).
|
|
212
|
-
*/
|
|
213
226
|
export function _countBy(items, mapper) {
|
|
214
227
|
const map = {};
|
|
215
|
-
|
|
216
|
-
|
|
228
|
+
let i = 0;
|
|
229
|
+
for (const item of items) {
|
|
230
|
+
const key = mapper(item, i++);
|
|
217
231
|
map[key] = (map[key] || 0) + 1;
|
|
218
|
-
}
|
|
232
|
+
}
|
|
219
233
|
return map;
|
|
220
234
|
}
|
|
221
235
|
// investigate: _groupBy
|
|
@@ -258,13 +272,23 @@ export function _difference(source, ...diffs) {
|
|
|
258
272
|
* Returns the sum of items, or 0 for empty array.
|
|
259
273
|
*/
|
|
260
274
|
export function _sum(items) {
|
|
261
|
-
|
|
275
|
+
let sum = 0;
|
|
276
|
+
for (const n of items) {
|
|
277
|
+
sum += n;
|
|
278
|
+
}
|
|
279
|
+
return sum;
|
|
262
280
|
}
|
|
263
281
|
export function _sumBy(items, mapper) {
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
282
|
+
let sum = 0;
|
|
283
|
+
let i = 0;
|
|
284
|
+
for (const n of items) {
|
|
285
|
+
const v = mapper(n, i++);
|
|
286
|
+
if (typeof v === 'number') {
|
|
287
|
+
// count only numbers, nothing else
|
|
288
|
+
sum += v;
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
return sum;
|
|
268
292
|
}
|
|
269
293
|
/**
|
|
270
294
|
* Map an array of T to a StringMap<V>,
|
|
@@ -330,7 +354,7 @@ export function _minOrUndefined(array) {
|
|
|
330
354
|
const a = array.filter(_isNotNullish);
|
|
331
355
|
if (!a.length)
|
|
332
356
|
return;
|
|
333
|
-
return
|
|
357
|
+
return a.reduce((min, item) => (min <= item ? min : item));
|
|
334
358
|
}
|
|
335
359
|
/**
|
|
336
360
|
* Filters out nullish values (undefined and null).
|
|
@@ -345,7 +369,7 @@ export function _maxOrUndefined(array) {
|
|
|
345
369
|
const a = array.filter(_isNotNullish);
|
|
346
370
|
if (!a.length)
|
|
347
371
|
return;
|
|
348
|
-
return
|
|
372
|
+
return a.reduce((max, item) => (max >= item ? max : item));
|
|
349
373
|
}
|
|
350
374
|
/**
|
|
351
375
|
* Filters out nullish values (undefined and null).
|
package/package.json
CHANGED
package/src/array/array.util.ts
CHANGED
|
@@ -195,31 +195,45 @@ export function _sortDescBy<T>(items: T[], mapper: Mapper<T, any>, mutate = fals
|
|
|
195
195
|
}
|
|
196
196
|
|
|
197
197
|
/**
|
|
198
|
-
*
|
|
198
|
+
* Similar to `Array.find`, but the `predicate` may return `END` to stop the iteration early.
|
|
199
199
|
*
|
|
200
|
-
*
|
|
201
|
-
* iOS Safari only has it since 15.4
|
|
200
|
+
* Use `Array.find` if you don't need to stop the iteration early.
|
|
202
201
|
*/
|
|
203
|
-
export function
|
|
204
|
-
|
|
202
|
+
export function _find<T>(items: readonly T[], predicate: AbortablePredicate<T>): T | undefined {
|
|
203
|
+
for (const [i, item] of items.entries()) {
|
|
204
|
+
const result = predicate(item, i)
|
|
205
|
+
if (result === END) return
|
|
206
|
+
if (result) return item
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
/**
|
|
211
|
+
* Similar to `Array.findLast`, but the `predicate` may return `END` to stop the iteration early.
|
|
212
|
+
*
|
|
213
|
+
* Use `Array.findLast` if you don't need to stop the iteration early, which is supported:
|
|
214
|
+
* - in Node since 18+
|
|
215
|
+
* - in iOS Safari since 15.4
|
|
216
|
+
*/
|
|
217
|
+
export function _findLast<T>(items: readonly T[], predicate: AbortablePredicate<T>): T | undefined {
|
|
218
|
+
return _find(items.slice().reverse(), predicate)
|
|
205
219
|
}
|
|
206
220
|
|
|
207
|
-
export function _takeWhile<T>(items: T[], predicate: Predicate<T>): T[] {
|
|
221
|
+
export function _takeWhile<T>(items: readonly T[], predicate: Predicate<T>): T[] {
|
|
208
222
|
let proceed = true
|
|
209
223
|
return items.filter((v, index) => (proceed &&= predicate(v, index)))
|
|
210
224
|
}
|
|
211
225
|
|
|
212
|
-
export function _takeRightWhile<T>(items: T[], predicate: Predicate<T>): T[] {
|
|
226
|
+
export function _takeRightWhile<T>(items: readonly T[], predicate: Predicate<T>): T[] {
|
|
213
227
|
let proceed = true
|
|
214
228
|
return [...items].reverse().filter((v, index) => (proceed &&= predicate(v, index)))
|
|
215
229
|
}
|
|
216
230
|
|
|
217
|
-
export function _dropWhile<T>(items: T[], predicate: Predicate<T>): T[] {
|
|
231
|
+
export function _dropWhile<T>(items: readonly T[], predicate: Predicate<T>): T[] {
|
|
218
232
|
let proceed = false
|
|
219
233
|
return items.filter((v, index) => (proceed ||= !predicate(v, index)))
|
|
220
234
|
}
|
|
221
235
|
|
|
222
|
-
export function _dropRightWhile<T>(items: T[], predicate: Predicate<T>): T[] {
|
|
236
|
+
export function _dropRightWhile<T>(items: readonly T[], predicate: Predicate<T>): T[] {
|
|
223
237
|
let proceed = false
|
|
224
238
|
return [...items]
|
|
225
239
|
.reverse()
|
|
@@ -232,12 +246,17 @@ export function _dropRightWhile<T>(items: T[], predicate: Predicate<T>): T[] {
|
|
|
232
246
|
*
|
|
233
247
|
* `limit` allows to exit early when limit count is reached, skipping further iterations (perf optimization).
|
|
234
248
|
*/
|
|
235
|
-
export function _count<T>(
|
|
249
|
+
export function _count<T>(
|
|
250
|
+
items: Iterable<T>,
|
|
251
|
+
predicate: AbortablePredicate<T>,
|
|
252
|
+
limit?: number,
|
|
253
|
+
): number {
|
|
236
254
|
if (limit === 0) return 0
|
|
237
255
|
let count = 0
|
|
256
|
+
let i = 0
|
|
238
257
|
|
|
239
|
-
for (const
|
|
240
|
-
const r = predicate(item, i)
|
|
258
|
+
for (const item of items) {
|
|
259
|
+
const r = predicate(item, i++)
|
|
241
260
|
if (r === END) break
|
|
242
261
|
if (r) {
|
|
243
262
|
count++
|
|
@@ -248,16 +267,14 @@ export function _count<T>(items: T[], predicate: AbortablePredicate<T>, limit?:
|
|
|
248
267
|
return count
|
|
249
268
|
}
|
|
250
269
|
|
|
251
|
-
|
|
252
|
-
* `limit` allows to exit early when limit count is reached, skipping further iterations (perf optimization).
|
|
253
|
-
*/
|
|
254
|
-
export function _countBy<T>(items: T[], mapper: Mapper<T, any>): StringMap<number> {
|
|
270
|
+
export function _countBy<T>(items: Iterable<T>, mapper: Mapper<T, any>): StringMap<number> {
|
|
255
271
|
const map: StringMap<number> = {}
|
|
256
272
|
|
|
257
|
-
|
|
258
|
-
|
|
273
|
+
let i = 0
|
|
274
|
+
for (const item of items) {
|
|
275
|
+
const key = mapper(item, i++)
|
|
259
276
|
map[key] = (map[key] || 0) + 1
|
|
260
|
-
}
|
|
277
|
+
}
|
|
261
278
|
|
|
262
279
|
return map
|
|
263
280
|
}
|
|
@@ -305,15 +322,27 @@ export function _difference<T>(source: T[], ...diffs: T[][]): T[] {
|
|
|
305
322
|
/**
|
|
306
323
|
* Returns the sum of items, or 0 for empty array.
|
|
307
324
|
*/
|
|
308
|
-
export function _sum(items: number
|
|
309
|
-
|
|
325
|
+
export function _sum(items: Iterable<number>): number {
|
|
326
|
+
let sum = 0
|
|
327
|
+
for (const n of items) {
|
|
328
|
+
sum += n
|
|
329
|
+
}
|
|
330
|
+
return sum
|
|
310
331
|
}
|
|
311
332
|
|
|
312
|
-
export function _sumBy<T>(items: T
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
333
|
+
export function _sumBy<T>(items: Iterable<T>, mapper: Mapper<T, number | undefined>): number {
|
|
334
|
+
let sum = 0
|
|
335
|
+
let i = 0
|
|
336
|
+
|
|
337
|
+
for (const n of items) {
|
|
338
|
+
const v = mapper(n, i++)
|
|
339
|
+
if (typeof v === 'number') {
|
|
340
|
+
// count only numbers, nothing else
|
|
341
|
+
sum += v
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
return sum
|
|
317
346
|
}
|
|
318
347
|
|
|
319
348
|
/**
|
|
@@ -330,7 +359,7 @@ export function _sumBy<T>(items: T[], mapper: Mapper<T, number | undefined>): nu
|
|
|
330
359
|
* // { '1': 'id1, '2': 'id2', '3': 'id3' }
|
|
331
360
|
*/
|
|
332
361
|
export function _mapToObject<T, V>(
|
|
333
|
-
array: T
|
|
362
|
+
array: Iterable<T>,
|
|
334
363
|
mapper: (item: T) => [key: any, value: V] | FalsyValue,
|
|
335
364
|
): StringMap<V> {
|
|
336
365
|
const m: StringMap<V> = {}
|
|
@@ -365,7 +394,7 @@ export function _shuffle<T>(array: T[], mutate = false): T[] {
|
|
|
365
394
|
* Returns last item of non-empty array.
|
|
366
395
|
* Throws if array is empty.
|
|
367
396
|
*/
|
|
368
|
-
export function _last<T>(array: T[]): T {
|
|
397
|
+
export function _last<T>(array: readonly T[]): T {
|
|
369
398
|
if (!array.length) throw new Error('_last called on empty array')
|
|
370
399
|
return array[array.length - 1]!
|
|
371
400
|
}
|
|
@@ -373,7 +402,7 @@ export function _last<T>(array: T[]): T {
|
|
|
373
402
|
/**
|
|
374
403
|
* Returns last item of the array (or undefined if array is empty).
|
|
375
404
|
*/
|
|
376
|
-
export function _lastOrUndefined<T>(array: T[]): T | undefined {
|
|
405
|
+
export function _lastOrUndefined<T>(array: readonly T[]): T | undefined {
|
|
377
406
|
return array[array.length - 1]
|
|
378
407
|
}
|
|
379
408
|
|
|
@@ -381,48 +410,48 @@ export function _lastOrUndefined<T>(array: T[]): T | undefined {
|
|
|
381
410
|
* Returns the first item of non-empty array.
|
|
382
411
|
* Throws if array is empty.
|
|
383
412
|
*/
|
|
384
|
-
export function _first<T>(array: T[]): T {
|
|
413
|
+
export function _first<T>(array: readonly T[]): T {
|
|
385
414
|
if (!array.length) throw new Error('_first called on empty array')
|
|
386
415
|
return array[0]!
|
|
387
416
|
}
|
|
388
417
|
|
|
389
|
-
export function _minOrUndefined<T>(array: T[]): NonNullable<T> | undefined {
|
|
418
|
+
export function _minOrUndefined<T>(array: readonly T[]): NonNullable<T> | undefined {
|
|
390
419
|
const a = array.filter(_isNotNullish)
|
|
391
420
|
if (!a.length) return
|
|
392
|
-
return
|
|
421
|
+
return a.reduce((min, item) => (min <= item ? min : item))
|
|
393
422
|
}
|
|
394
423
|
|
|
395
424
|
/**
|
|
396
425
|
* Filters out nullish values (undefined and null).
|
|
397
426
|
*/
|
|
398
|
-
export function _min<T>(array: T[]): NonNullable<T> {
|
|
427
|
+
export function _min<T>(array: readonly T[]): NonNullable<T> {
|
|
399
428
|
const a = array.filter(_isNotNullish)
|
|
400
429
|
if (!a.length) throw new Error('_min called on empty array')
|
|
401
430
|
return a.reduce((min, item) => (min <= item ? min : item))
|
|
402
431
|
}
|
|
403
432
|
|
|
404
|
-
export function _maxOrUndefined<T>(array: T[]): NonNullable<T> | undefined {
|
|
433
|
+
export function _maxOrUndefined<T>(array: readonly T[]): NonNullable<T> | undefined {
|
|
405
434
|
const a = array.filter(_isNotNullish)
|
|
406
435
|
if (!a.length) return
|
|
407
|
-
return
|
|
436
|
+
return a.reduce((max, item) => (max >= item ? max : item))
|
|
408
437
|
}
|
|
409
438
|
|
|
410
439
|
/**
|
|
411
440
|
* Filters out nullish values (undefined and null).
|
|
412
441
|
*/
|
|
413
|
-
export function _max<T>(array: T[]): NonNullable<T> {
|
|
442
|
+
export function _max<T>(array: readonly T[]): NonNullable<T> {
|
|
414
443
|
const a = array.filter(_isNotNullish)
|
|
415
444
|
if (!a.length) throw new Error('_max called on empty array')
|
|
416
445
|
return a.reduce((max, item) => (max >= item ? max : item))
|
|
417
446
|
}
|
|
418
447
|
|
|
419
|
-
export function _maxBy<T>(array: T[], mapper: Mapper<T, number | string | undefined>): T {
|
|
448
|
+
export function _maxBy<T>(array: readonly T[], mapper: Mapper<T, number | string | undefined>): T {
|
|
420
449
|
const max = _maxByOrUndefined(array, mapper)
|
|
421
450
|
if (max === undefined) throw new Error(`_maxBy returned undefined`)
|
|
422
451
|
return max
|
|
423
452
|
}
|
|
424
453
|
|
|
425
|
-
export function _minBy<T>(array: T[], mapper: Mapper<T, number | string | undefined>): T {
|
|
454
|
+
export function _minBy<T>(array: readonly T[], mapper: Mapper<T, number | string | undefined>): T {
|
|
426
455
|
const min = _minByOrUndefined(array, mapper)
|
|
427
456
|
if (min === undefined) throw new Error(`_minBy returned undefined`)
|
|
428
457
|
return min
|
|
@@ -431,7 +460,7 @@ export function _minBy<T>(array: T[], mapper: Mapper<T, number | string | undefi
|
|
|
431
460
|
// todo: looks like it _maxByOrUndefined/_minByOrUndefined can be DRYer
|
|
432
461
|
|
|
433
462
|
export function _maxByOrUndefined<T>(
|
|
434
|
-
array: T[],
|
|
463
|
+
array: readonly T[],
|
|
435
464
|
mapper: Mapper<T, number | string | undefined>,
|
|
436
465
|
): T | undefined {
|
|
437
466
|
if (!array.length) return
|
|
@@ -450,7 +479,7 @@ export function _maxByOrUndefined<T>(
|
|
|
450
479
|
}
|
|
451
480
|
|
|
452
481
|
export function _minByOrUndefined<T>(
|
|
453
|
-
array: T[],
|
|
482
|
+
array: readonly T[],
|
|
454
483
|
mapper: Mapper<T, number | string | undefined>,
|
|
455
484
|
): T | undefined {
|
|
456
485
|
if (!array.length) return
|
|
@@ -468,7 +497,7 @@ export function _minByOrUndefined<T>(
|
|
|
468
497
|
return minItem
|
|
469
498
|
}
|
|
470
499
|
|
|
471
|
-
export function _zip<T1, T2>(array1: T1[], array2: T2[]): [T1, T2][] {
|
|
500
|
+
export function _zip<T1, T2>(array1: readonly T1[], array2: readonly T2[]): [T1, T2][] {
|
|
472
501
|
const len = Math.min(array1.length, array2.length)
|
|
473
502
|
const res: [T1, T2][] = []
|
|
474
503
|
|