@rimbu/common 1.1.0 → 2.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.
@@ -1,542 +0,0 @@
1
- import { CollectFun, Eq, OptLazy } from './internal.mjs';
2
- /**
3
- * A `Reducer` is a stand-alone calculation that takes input values of type I, and, when requested, produces an output value of type O.
4
- * @typeparam I - the input value type
5
- * @typeparam O - the output value type
6
- */
7
- export type Reducer<I, O = I> = Reducer.Impl<I, O, unknown>;
8
- export declare namespace Reducer {
9
- /**
10
- * The Implementation interface for a `Reducer`, which also exposes the internal state type.
11
- * @typeparam I - the input value type
12
- * @typeparam O - the output value type
13
- * @typeparam S - the internal state type
14
- */
15
- interface Impl<I, O, S> {
16
- /**
17
- * The initial state value for the reducer algorithm.
18
- */
19
- readonly init: OptLazy<S>;
20
- /**
21
- * Returns the next state based on the given input values
22
- * @param state - the current state
23
- * @param elem - the current input value
24
- * @param index - the current input index
25
- * @param halt - a function that, when called, ensures no more values are passed to the reducer
26
- */
27
- next(state: S, elem: I, index: number, halt: () => void): S;
28
- /**
29
- * Returns the output value based on the given `state`
30
- * @param state - the current state
31
- */
32
- stateToResult(state: S): O;
33
- /**
34
- * Returns a `Reducer` instance that only passes values to the reducer that satisy the given `pred` predicate.
35
- * @param pred - a function that returns true if the value should be passed to the reducer based on the following inputs:<br/>
36
- * - value: the current input value<br/>
37
- * - index: the current input index<br/>
38
- * - halt: function that, when called, ensures no more new values are passed to the reducer
39
- * @example
40
- * ```ts
41
- * Reducer.sum.filterInput(v => v > 10)
42
- * // this reducer will only sum values larger than 10
43
- * ```
44
- */
45
- filterInput(pred: (value: I, index: number, halt: () => void) => boolean): Reducer<I, O>;
46
- /**
47
- * Returns a `Reducer` instance that converts its input values using given `mapFun` before passing them to the reducer.
48
- * @typeparam I2 - the resulting reducer input type
49
- * @param mapFun - a function that returns a new value to pass to the reducer based on the following inputs:<br/>
50
- * - value: the current input value<br/>
51
- * - index: the current input index
52
- * @example
53
- * ```ts
54
- * Reducer.sum.mapInput(v => v * 2)
55
- * // this reducer will double all input values before summing them
56
- * ```
57
- */
58
- mapInput<I2>(mapFun: (value: I2, index: number) => I): Reducer<I2, O>;
59
- /**
60
- * Returns a `Reducer` instance that converts or filters its input values using given `collectFun` before passing them to the reducer.
61
- * @typeparam I2 - the resulting reducer input type
62
- * @param collectFun - a function receiving<br/>
63
- * - `value`: the next value<br/>
64
- * - `index`: the value index<br/>
65
- * - `skip`: a token that, when returned, will not add a value to the resulting collection<br/>
66
- * - `halt`: a function that, when called, ensures no next elements are passed
67
- * @example
68
- * ```ts
69
- * Reducer.sum.collectInput((v, _, skip) => v <= 10 ? skip : v * 2)
70
- * // this reducer will double all input values larger thant 10 before summing them,
71
- * // and will skip all values smaller than 10
72
- * ```
73
- */
74
- collectInput<I2>(collectFun: CollectFun<I2, I>): Reducer<I2, O>;
75
- /**
76
- * Returns a `Reducer` instance that converts its output values using given `mapFun`.
77
- * @typeparam O2 - the resulting reducer output type
78
- * @param mapFun - a function that takes the current output value and converts it to a new output value
79
- * @example
80
- * ```ts
81
- * Reducer.sum.mapOutput(String)
82
- * // this reducer will convert all its results to string before returning them
83
- * ```
84
- */
85
- mapOutput<O2>(mapFun: (value: O) => O2): Reducer<I, O2>;
86
- /**
87
- * Returns a `Reducer` instance that takes at most the given `amount` of input elements, and will ignore subsequent elements.
88
- * @param amount - the amount of elements to accept
89
- * @example
90
- * ```ts
91
- * Stream.range({ end: 10 }).reduce(Reducer.sum.takeInput(2))
92
- * // => 1
93
- * ```
94
- */
95
- takeInput(amount: number): Reducer<I, O>;
96
- /**
97
- * Returns a `Reducer` instance that skips the first given `amount` of input elements, and will process subsequent elements.
98
- * @param amount - the amount of elements to skip
99
- * @example
100
- * ```ts
101
- * Stream.range({ end: 10 }).reduce(Reducer.sum.dropInput(9))
102
- * // => 19
103
- * ```
104
- */
105
- dropInput(amount: number): Reducer<I, O>;
106
- /**
107
- * Returns a `Reducer` instance that takes given `amount` of elements starting at given `from` index, and ignores other elements.
108
- * @param from - (default: 0) the index at which to start processing elements
109
- * @param amount - (optional) the amount of elements to process, if not given, processes all elements from the `from` index
110
- * @example
111
- * ```ts
112
- * Stream.range({ end: 10 }).reduce(Reducer.sum.sliceInput(1, 2))
113
- * // => 3
114
- * ```
115
- */
116
- sliceInput(from?: number, amount?: number): Reducer<I, O>;
117
- }
118
- /**
119
- * A base class that can be used to easily create `Reducer` instances.
120
- * @typeparam I - the input value type
121
- * @typeparam O - the output value type
122
- * @typeparam S - the internal state type
123
- */
124
- class Base<I, O, S> implements Reducer.Impl<I, O, S> {
125
- readonly init: OptLazy<S>;
126
- readonly next: (state: S, elem: I, index: number, halt: () => void) => S;
127
- readonly stateToResult: (state: S) => O;
128
- constructor(init: OptLazy<S>, next: (state: S, elem: I, index: number, halt: () => void) => S, stateToResult: (state: S) => O);
129
- filterInput(pred: (value: I, index: number, halt: () => void) => boolean): Reducer<I, O>;
130
- mapInput<I2>(mapFun: (value: I2, index: number) => I): Reducer<I2, O>;
131
- collectInput<I2>(collectFun: CollectFun<I2, I>): Reducer<I2, O>;
132
- mapOutput<O2>(mapFun: (value: O) => O2): Reducer<I, O2>;
133
- takeInput(amount: number): Reducer<I, O>;
134
- dropInput(amount: number): Reducer<I, O>;
135
- sliceInput(from?: number, amount?: number): Reducer<I, O>;
136
- }
137
- /**
138
- * Returns a `Reducer` with the given options:
139
- * @param init - the initial state value
140
- * @param next - returns the next state value based on the given inputs:<br/>
141
- * - current: the current state<br/>
142
- * - next: the current input value<br/>
143
- * - index: the input index value<br/>
144
- * - halt: function that, when called, ensures no more elements are passed to the reducer
145
- * @param stateToResult - a function that converts the current state to an output value
146
- * @typeparam I - the input value type
147
- * @typeparam O - the output value type
148
- * @typeparam S - the internal state type
149
- * @example
150
- * ```ts
151
- * const evenNumberOfOnes = Reducer
152
- * .create(
153
- * true,
154
- * (current, value: number) => value === 1 ? !current : current,
155
- * state => state ? 'even' : 'not even')
156
- * const result = Stream.of(1, 2, 3, 2, 1)).reduce(evenNumberOfOnes)
157
- * console.log+(result)
158
- * // => 'even'
159
- * ```
160
- */
161
- function create<I, O = I, S = O>(init: OptLazy<S>, next: (current: S, next: I, index: number, halt: () => void) => S, stateToResult: (state: S) => O): Reducer<I, O>;
162
- /**
163
- * Returns a `Reducer` of which the input, state, and output types are the same.
164
- * @param init - the initial state value
165
- * @param next - returns the next state value based on the given inputs:<br/>
166
- * - current: the current state<br/>
167
- * - next: the current input value<br/>
168
- * - index: the input index value<br/>
169
- * - halt: function that, when called, ensures no more elements are passed to the reducer
170
- * @param stateToResult - (optional) a function that converts the current state to an output value
171
- * @typeparam T - the overall value type
172
- * @example
173
- * ```ts
174
- * const sum = Reducer
175
- * .createMono(
176
- * 0,
177
- * (current, value) => current + value
178
- * )
179
- * const result = Stream.of(1, 2, 3, 2, 1)).reduce(sum)
180
- * console.log+(result)
181
- * // => 9
182
- * ```
183
- */
184
- function createMono<T>(init: OptLazy<T>, next: (current: T, next: T, index: number, halt: () => void) => T, stateToResult?: (state: T) => T): Reducer<T>;
185
- /**
186
- * Returns a `Reducer` of which the state and output types are the same.
187
- * @param init - the initial state value
188
- * @param next - returns the next state value based on the given inputs:<br/>
189
- * - current: the current state<br/>
190
- * - next: the current input value<br/>
191
- * - index: the input index value<br/>
192
- * - halt: function that, when called, ensures no more elements are passed to the reducer
193
- * @param stateToResult - (optional) a function that converts the current state to an output value
194
- * @typeparam I - the input value type
195
- * @typeparam O - the output value type
196
- * @example
197
- * ```ts
198
- * const boolToString = Reducer
199
- * .createOutput(
200
- * '',
201
- * (current, value: boolean) => current + (value ? 'T' : 'F')
202
- * )
203
- * const result = Stream.of(true, false, true)).reduce(boolToString)
204
- * console.log+(result)
205
- * // => 'TFT'
206
- * ```
207
- */
208
- function createOutput<I, O = I>(init: OptLazy<O>, next: (current: O, next: I, index: number, halt: () => void) => O, stateToResult?: (state: O) => O): Reducer<I, O>;
209
- /**
210
- * A `Reducer` that sums all given numeric input values.
211
- * @example
212
- * ```ts
213
- * console.log(Stream.range({ amount: 5 }).reduce(Reducer.sum))
214
- * // => 10
215
- * ```
216
- */
217
- const sum: Reducer<number, number>;
218
- /**
219
- * A `Reducer` that calculates the product of all given numeric input values.
220
- * @example
221
- * ```ts
222
- * console.log(Stream.range({ start: 1, amount: 5 }).reduce(product))
223
- * // => 120
224
- * ```
225
- */
226
- const product: Reducer<number, number>;
227
- /**
228
- * A `Reducer` that calculates the average of all given numberic input values.
229
- * @example
230
- * ```ts
231
- * console.log(Stream.range({ amount: 5 }).reduce(Reducer.average));
232
- * // => 2
233
- * ```
234
- */
235
- const average: Reducer<number, number>;
236
- /**
237
- * Returns a `Reducer` that remembers the minimum value of the inputs using the given `compFun` to compare input values
238
- * @param compFun - a comparison function for two input values, returning 0 when equal, positive when greater, negetive when smaller
239
- * @param otherwise - (default: undefineds) a fallback value when there were no input values given
240
- * @example
241
- * ```ts
242
- * const stream = Stream.of('abc', 'a', 'abcde', 'ab')
243
- * console.log(stream.minBy((s1, s2) => s1.length - s2.length))
244
- * // 'a'
245
- * ```
246
- */
247
- const minBy: {
248
- <T>(compFun: (v1: T, v2: T) => number): Reducer<T, T | undefined>;
249
- <T, O>(compFun: (v1: T, v2: T) => number, otherwise: OptLazy<O>): Reducer<T, T | O>;
250
- };
251
- /**
252
- * Returns a `Reducer` that remembers the minimum value of the numberic inputs.
253
- * @param otherwise - (default: undefined) a fallback value when there were no input values given
254
- * @example
255
- * ```ts
256
- * console.log(Stream.of(5, 3, 7, 4).reduce(Reducer.min()))
257
- * // => 3
258
- * ```
259
- */
260
- const min: {
261
- (): Reducer<number, number | undefined>;
262
- <O>(otherwise: OptLazy<O>): Reducer<number, number | O>;
263
- };
264
- /**
265
- * Returns a `Reducer` that remembers the maximum value of the inputs using the given `compFun` to compare input values
266
- * @param compFun - a comparison function for two input values, returning 0 when equal, positive when greater, negetive when smaller
267
- * @param otherwise - (default: undefined) a fallback value when there were no input values given
268
- * @example
269
- * ```ts
270
- * const stream = Stream.of('abc', 'a', 'abcde', 'ab')
271
- * console.log(stream.maxBy((s1, s2) => s1.length - s2.length))
272
- * // 'abcde'
273
- * ```
274
- */
275
- const maxBy: {
276
- <T>(compFun: (v1: T, v2: T) => number): Reducer<T, T | undefined>;
277
- <T, O>(compFun: (v1: T, v2: T) => number, otherwise: OptLazy<O>): Reducer<T, T | O>;
278
- };
279
- /**
280
- * Returns a `Reducer` that remembers the maximum value of the numberic inputs.
281
- * @param otherwise - (default: undefined) a fallback value when there were no input values given
282
- * @example
283
- * ```ts
284
- * console.log(Stream.of(5, 3, 7, 4).reduce(Reducer.max()))
285
- * // => 7
286
- * ```
287
- */
288
- const max: {
289
- (): Reducer<number, number | undefined>;
290
- <O>(otherwise: OptLazy<O>): Reducer<number, number | O>;
291
- };
292
- /**
293
- * Returns a `Reducer` that joins the given input values into a string using the given options.
294
- * @param options - an object containing:<br/>
295
- * - sep: (optional) a seperator string value between values in the output<br/>
296
- * - start: (optional) a start string to prepend to the output<br/>
297
- * - end: (optional) an end string to append to the output<br/>
298
- * @example
299
- * ```ts
300
- * console.log(Stream.of(1, 2, 3).reduce(Reducer.join({ sep: '-' })))
301
- * // => '1-2-3'
302
- * ```
303
- */
304
- function join<T>({ sep, start, end, valueToString, }?: {
305
- sep?: string | undefined;
306
- start?: string | undefined;
307
- end?: string | undefined;
308
- valueToString?: ((value: T) => string) | undefined;
309
- }): Reducer<T, string>;
310
- /**
311
- * Returns a `Reducer` that remembers the amount of input items provided.
312
- * @param pred - (optional) a predicate that returns false if the item should not be counted given:<br/>
313
- * - value: the current input value<br/>
314
- * - index: the input value index
315
- * @example
316
- * ```ts
317
- * const stream = Stream.range({ amount: 10 })
318
- * console.log(stream.reduce(Reducer.count()))
319
- * // => 10
320
- * console.log(stream.reduce(Reducer.count(v => v < 5)))
321
- * // => 5
322
- * ```
323
- */
324
- const count: {
325
- (): Reducer<never, number>;
326
- <T>(pred: (value: T, index: number) => boolean): Reducer<T, number>;
327
- };
328
- /**
329
- * Returns a `Reducer` that remembers the first input value for which the given `pred` function returns true.
330
- * @param pred - a function taking an input value and its index, and returning true if the value should be remembered
331
- * @param otherwise - (default: undefined) a fallback value to output if no input value yet has satisfied the given predicate
332
- * @typeparam T - the input value type
333
- * @typeparam O - the fallback value type
334
- * @example
335
- * ```ts
336
- * console.log(Stream.range({ amount: 10 }).reduce(Reducer.firstWhere(v => v > 5)))
337
- * // => 6
338
- * ```
339
- */
340
- const firstWhere: {
341
- <T>(pred: (value: T, index: number) => boolean): Reducer<T, T | undefined>;
342
- <T, O>(pred: (value: T, index: number) => boolean, otherwise: OptLazy<O>): Reducer<T, T | O>;
343
- };
344
- /**
345
- * Returns a `Reducer` that remembers the first input value.
346
- * @param otherwise - (default: undefined) a fallback value to output if no input value has been provided
347
- * @typeparam T - the input value type
348
- * @typeparam O - the fallback value type
349
- * @example
350
- * ```ts
351
- * console.log(Stream.range{ amount: 10 }).reduce(Reducer.first())
352
- * // => 0
353
- * ```
354
- */
355
- const first: {
356
- <T>(): Reducer<T, T | undefined>;
357
- <T, O>(otherwise: OptLazy<O>): Reducer<T, T | O>;
358
- };
359
- /**
360
- * Returns a `Reducer` that remembers the last input value for which the given `pred` function returns true.
361
- * @param pred - a function taking an input value and its index, and returning true if the value should be remembered
362
- * @param otherwise - (default: undefined) a fallback value to output if no input value yet has satisfied the given predicate
363
- * @typeparam T - the input value type
364
- * @typeparam O - the fallback value type
365
- * @example
366
- * ```ts
367
- * console.log(Stream.range({ amount: 10 }).reduce(Reducer.lastWhere(v => v > 5)))
368
- * // => 9
369
- * ```
370
- */
371
- const lastWhere: {
372
- <T>(pred: (value: T, index: number) => boolean): Reducer<T, T | undefined>;
373
- <T, O>(pred: (value: T, index: number) => boolean, otherwise: OptLazy<O>): Reducer<T, T | O>;
374
- };
375
- /**
376
- * Returns a `Reducer` that remembers the last input value.
377
- * @param otherwise - (default: undefined) a fallback value to output if no input value has been provided
378
- * @typeparam T - the input value type
379
- * @typeparam O - the fallback value type
380
- * @example
381
- * ```ts
382
- * console.log(Stream.range{ amount: 10 }).reduce(Reducer.last())
383
- * // => 9
384
- * ```
385
- */
386
- const last: {
387
- <T>(): Reducer<T, T | undefined>;
388
- <T, O>(otherwise: OptLazy<O>): Reducer<T, T | O>;
389
- };
390
- /**
391
- * Returns a `Reducer` that ouputs false as long as no input value satisfies given `pred`, true otherwise.
392
- * @typeparam T - the element type
393
- * @param pred - a function taking an input value and its index, and returning true if the value satisfies the predicate
394
- * @example
395
- * ```ts
396
- * console.log(Stream.range{ amount: 10 }).reduce(Reducer.some(v => v > 5))
397
- * // => true
398
- * ```
399
- */
400
- function some<T>(pred: (value: T, index: number) => boolean): Reducer<T, boolean>;
401
- /**
402
- * Returns a `Reducer` that ouputs true as long as all input values satisfy the given `pred`, false otherwise.
403
- * @typeparam T - the element type
404
- * @param pred - a function taking an input value and its index, and returning true if the value satisfies the predicate
405
- * @example
406
- * ```ts
407
- * console.log(Stream.range{ amount: 10 }).reduce(Reducer.every(v => v < 5))
408
- * // => false
409
- * ```
410
- */
411
- function every<T>(pred: (value: T, index: number) => boolean): Reducer<T, boolean>;
412
- /**
413
- * Returns a `Reducer` that outputs false as long as the given `elem` has not been encountered in the input values, true otherwise.
414
- * @typeparam T - the element type
415
- * @param elem - the element to search for
416
- * @param eq - (optional) a comparison function that returns true if te two given input values are considered equal
417
- * @example
418
- * ```ts
419
- * console.log(Stream.range({ amount: 10 }).reduce(Reducer.contains(5)))
420
- * // => true
421
- * ```
422
- */
423
- function contains<T>(elem: T, eq?: Eq<T>): Reducer<T, boolean>;
424
- /**
425
- * Returns a `Reducer` that takes boolean values and outputs true if all input values are true, and false otherwise.
426
- * @example
427
- * ```ts
428
- * console.log(Stream.of(true, false, true)).reduce(Reducer.and))
429
- * // => false
430
- * ```
431
- */
432
- const and: Reducer<boolean, boolean>;
433
- /**
434
- * Returns a `Reducer` that takes boolean values and outputs true if one or more input values are true, and false otherwise.
435
- * @example
436
- * ```ts
437
- * console.log(Stream.of(true, false, true)).reduce(Reducer.or))
438
- * // => true
439
- * ```
440
- */
441
- const or: Reducer<boolean, boolean>;
442
- /**
443
- * Returns a `Reducer` that outputs true if no input values are received, false otherwise.
444
- * @example
445
- * ```ts
446
- * console.log(Stream.of(1, 2, 3).reduce(Reducer.isEmpty))
447
- * // => false
448
- * ```
449
- */
450
- const isEmpty: Reducer<never, boolean>;
451
- /**
452
- * Returns a `Reducer` that outputs true if one or more input values are received, false otherwise.
453
- * @example
454
- * ```ts
455
- * console.log(Stream.of(1, 2, 3).reduce(Reducer.nonEmpty))
456
- * // => true
457
- * ```
458
- */
459
- const nonEmpty: Reducer<never, boolean>;
460
- /**
461
- * Returns a `Reducer` that collects received input values in an array, and returns a copy of that array as an output value when requested.
462
- * @typeparam T - the element type
463
- * @example
464
- * ```ts
465
- * console.log(Stream.of(1, 2, 3).reduce(Reducer.toArray()))
466
- * // => [1, 2, 3]
467
- * ```
468
- */
469
- function toArray<T>(): Reducer<T, T[]>;
470
- /**
471
- * Returns a `Reducer` that collects received input tuples into a mutable JS Map, and returns
472
- * a copy of that map when output is requested.
473
- * @typeparam K - the map key type
474
- * @typeparam V - the map value type
475
- * @example
476
- * ```ts
477
- * console.log(Stream.of([1, 'a'], [2, 'b']).reduce(Reducer.toJSMap()))
478
- * // Map { 1 => 'a', 2 => 'b' }
479
- * ```
480
- */
481
- function toJSMap<K, V>(): Reducer<[K, V], Map<K, V>>;
482
- /**
483
- * Returns a `Reducer` that collects received input values into a mutable JS Set, and returns
484
- * a copy of that map when output is requested.
485
- * @typeparam T - the element type
486
- * @example
487
- * ```ts
488
- * console.log(Stream.of(1, 2, 3).reduce(Reducer.toJSSet()))
489
- * // Set {1, 2, 3}
490
- * ```
491
- */
492
- function toJSSet<T>(): Reducer<T, Set<T>>;
493
- /**
494
- * Returns a `Reducer` that collects 2-tuples containing keys and values into a plain JS object, and
495
- * returns a copy of that object when output is requested.
496
- * @typeparam K - the result object key type
497
- * @typeparam V - the result object value type
498
- * @example
499
- * ```ts
500
- * console.log(Stream.of(['a', 1], ['b', true]).reduce(Reducer.toJSObject()))
501
- * // { a: 1, b: true }
502
- * ```
503
- */
504
- function toJSObject<K extends string | number | symbol, V>(): Reducer<[
505
- K,
506
- V
507
- ], Record<K, V>>;
508
- /**
509
- * Returns a `Reducer` that combines multiple input `reducers` by providing input values to all of them and collecting the outputs in an array.
510
- * @param reducers - 2 or more reducers to combine
511
- * @example
512
- * ```ts
513
- * const red = Reducer.combineArr(Reducer.sum, Reducer.average)
514
- * console.log(Stream.range({amount: 9 }).reduce(red))
515
- * // => [36, 4]
516
- * ```
517
- */
518
- function combineArr<T, R extends readonly [unknown, unknown, ...unknown[]]>(...reducers: {
519
- [K in keyof R]: Reducer<T, R[K]>;
520
- } & Reducer<T, unknown>[]): Reducer<T, R>;
521
- /**
522
- * Returns a `Reducer` that combines multiple input `reducers` by providing input values to all of them and collecting the outputs in the shape of the given object.
523
- * @typeparam T - the input type for all the reducers
524
- * @typeparam R - the result object shape
525
- * @param reducerObj - an object of keys, and reducers corresponding to those keys
526
- * @example
527
- * ```ts
528
- * const red = Reducer.combineObj({
529
- * theSum: Reducer.sum,
530
- * theAverage: Reducer.average
531
- * });
532
- *
533
- * Stream.range({ amount: 9 }).reduce(red);
534
- * // => { theSum: 36, theAverage: 4 }
535
- * ```
536
- */
537
- function combineObj<T, R extends {
538
- readonly [key: string]: unknown;
539
- }>(reducerObj: {
540
- readonly [K in keyof R]: Reducer<T, R[K]>;
541
- } & Record<string, Reducer<T, unknown>>): Reducer<T, R>;
542
- }