scats 1.0.32 → 1.2.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 +82 -3
- package/coverage/clover.xml +937 -0
- package/coverage/coverage-final.json +15 -0
- package/coverage/lcov-report/array-iterable.ts.html +1709 -0
- package/coverage/lcov-report/base.css +224 -0
- package/coverage/lcov-report/block-navigation.js +79 -0
- package/coverage/lcov-report/collection.ts.html +1475 -0
- package/coverage/lcov-report/either.ts.html +1934 -0
- package/coverage/lcov-report/favicon.png +0 -0
- package/coverage/lcov-report/hashmap.ts.html +527 -0
- package/coverage/lcov-report/hashset.ts.html +392 -0
- package/coverage/lcov-report/index.html +126 -0
- package/coverage/lcov-report/index.ts.html +101 -0
- package/coverage/lcov-report/option.ts.html +758 -0
- package/coverage/lcov-report/prettify.css +1 -0
- package/coverage/lcov-report/prettify.js +2 -0
- package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
- package/coverage/lcov-report/sorter.js +170 -0
- package/coverage/lcov-report/src/abstract-map.ts.html +317 -0
- package/coverage/lcov-report/src/abstract-set.ts.html +200 -0
- package/coverage/lcov-report/src/array-iterable.ts.html +1751 -0
- package/coverage/lcov-report/src/collection.ts.html +1778 -0
- package/coverage/lcov-report/src/either.ts.html +1934 -0
- package/coverage/lcov-report/src/hashmap.ts.html +428 -0
- package/coverage/lcov-report/src/hashset.ts.html +482 -0
- package/coverage/lcov-report/src/index.html +276 -0
- package/coverage/lcov-report/src/index.ts.html +110 -0
- package/coverage/lcov-report/src/mutable/hashmap.ts.html +821 -0
- package/coverage/lcov-report/src/mutable/hashset.ts.html +611 -0
- package/coverage/lcov-report/src/mutable/index.html +126 -0
- package/coverage/lcov-report/src/mutable.ts.html +89 -0
- package/coverage/lcov-report/src/option.ts.html +758 -0
- package/coverage/lcov-report/src/try.ts.html +923 -0
- package/coverage/lcov-report/src/util.ts.html +518 -0
- package/coverage/lcov-report/try.ts.html +923 -0
- package/coverage/lcov-report/util.ts.html +518 -0
- package/coverage/lcov.info +2223 -0
- package/dist/abstract-map.d.ts +25 -0
- package/dist/abstract-map.js +62 -0
- package/dist/abstract-set.d.ts +13 -0
- package/dist/abstract-set.js +33 -0
- package/dist/array-iterable.d.ts +1 -3
- package/dist/array-iterable.js +21 -23
- package/dist/collection.d.ts +59 -20
- package/dist/collection.js +254 -62
- package/dist/hashmap.d.ts +12 -26
- package/dist/hashmap.js +39 -58
- package/dist/hashset.d.ts +12 -17
- package/dist/hashset.js +25 -35
- package/dist/index.d.ts +2 -0
- package/dist/index.js +3 -0
- package/dist/mutable/hashmap.d.ts +24 -0
- package/dist/mutable/hashmap.js +118 -0
- package/dist/mutable/hashset.d.ts +20 -0
- package/dist/mutable/hashset.js +88 -0
- package/dist/mutable.d.ts +3 -0
- package/dist/mutable.js +9 -0
- package/dist/option.js +1 -1
- package/package.json +12 -12
- package/src/abstract-map.ts +79 -0
- package/src/abstract-set.ts +40 -0
- package/src/array-iterable.ts +26 -12
- package/src/collection.ts +394 -85
- package/src/either.ts +2 -2
- package/src/hashmap.ts +74 -73
- package/src/hashset.ts +82 -42
- package/src/index.ts +3 -0
- package/src/mutable/hashmap.ts +247 -0
- package/src/mutable/hashset.ts +177 -0
- package/src/mutable.ts +3 -0
- package/src/option.ts +2 -2
- package/src/try.ts +9 -9
package/src/collection.ts
CHANGED
|
@@ -1,15 +1,102 @@
|
|
|
1
|
-
import {HashMap} from './hashmap';
|
|
2
|
-
import {HashSet} from './hashset';
|
|
3
|
-
import {ArrayIterable} from './array-iterable';
|
|
4
1
|
import {Mappable} from './mappable';
|
|
2
|
+
import {HashMap, HashSet, Option} from './index';
|
|
5
3
|
import {Filterable} from './util';
|
|
4
|
+
import {ArrayIterable} from './array-iterable';
|
|
5
|
+
|
|
6
|
+
export abstract class ArrayBackedCollection<T, C extends ArrayIterable<T, any>> extends ArrayIterable<T, C> {
|
|
6
7
|
|
|
7
|
-
|
|
8
|
-
implements Mappable<T>,
|
|
9
|
-
Filterable<T, Collection<T>> {
|
|
8
|
+
protected abstract readonly items: T[];
|
|
10
9
|
|
|
11
10
|
|
|
12
|
-
|
|
11
|
+
protected checkWithinBounds(lo: number, hi: number): void {
|
|
12
|
+
if (lo < 0) throw new Error(`$lo is out of bounds (min 0, max ${this.items.length - 1})`);
|
|
13
|
+
if (hi > this.size) throw new Error(`$lo is out of bounds (min 0, max ${this.items.length - 1})`);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
get reverse(): C {
|
|
17
|
+
return this.fromArray(this.items.reverse());
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
get toArray(): T[] {
|
|
21
|
+
return this.items;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
get(index: number): T {
|
|
25
|
+
this.checkWithinBounds(index, index + 1);
|
|
26
|
+
return this.items[index];
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
get toSet(): HashSet<T> {
|
|
30
|
+
return HashSet.of(...this.items);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
indexOf(item: T): number {
|
|
35
|
+
return this.items.indexOf(item);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
get distinct(): C {
|
|
39
|
+
return this.fromArray(Array.from(new Set(this.items)));
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
distinctBy(key: (item: T) => string | number): C {
|
|
43
|
+
const keys = new Set();
|
|
44
|
+
const res: T[] = [];
|
|
45
|
+
this.foreach(item => {
|
|
46
|
+
const currentKey = key(item);
|
|
47
|
+
if (!keys.has(currentKey)) {
|
|
48
|
+
keys.add(currentKey);
|
|
49
|
+
res.push(item);
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
return this.fromArray(res);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
appended(item: T): C {
|
|
56
|
+
return this.fromArray(this.items.concat([item]));
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
appendedAll(other: Iterable<T>): C {
|
|
60
|
+
return this.fromArray(this.items.concat(...other));
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
prepended(item: T): C {
|
|
64
|
+
return this.fromArray([item].concat(this.items));
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
prependedAll(other: Iterable<T>): C {
|
|
68
|
+
return this.fromArray(Array.from(other).concat(this.items));
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
concat(other: Iterable<T>): C {
|
|
72
|
+
return this.appendedAll(other);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
slice(from: number, until: number): C {
|
|
76
|
+
return this.fromArray(this.items.slice(from, until));
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
sort(param: (a: T, b: T) => number): C {
|
|
80
|
+
return this.fromArray(this.items.slice(0).sort(param));
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
sortBy(fieldToNumber: (a: T) => number): C {
|
|
85
|
+
return this.sort(((a, b) => fieldToNumber(a) - fieldToNumber(b)));
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
get length(): number {
|
|
89
|
+
return this.size;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
export class Collection<T> extends ArrayBackedCollection<T, Collection<T>> implements Mappable<T>,
|
|
97
|
+
Filterable<T, Collection<T>> {
|
|
98
|
+
|
|
99
|
+
constructor(protected readonly items: T[]) {
|
|
13
100
|
super();
|
|
14
101
|
}
|
|
15
102
|
|
|
@@ -23,12 +110,14 @@ export class Collection<T> extends ArrayIterable<T, Collection<T>>
|
|
|
23
110
|
}
|
|
24
111
|
}
|
|
25
112
|
|
|
26
|
-
|
|
27
|
-
|
|
28
113
|
static of<T>(...items: T[]): Collection<T> {
|
|
29
114
|
return new Collection<T>(items);
|
|
30
115
|
}
|
|
31
116
|
|
|
117
|
+
static from<T>(elements: Iterable<T>): Collection<T> {
|
|
118
|
+
return new Collection<T>(Array.from(elements));
|
|
119
|
+
}
|
|
120
|
+
|
|
32
121
|
static fill<A>(len: number): (elem: (idx: number) => A) => Collection<A> {
|
|
33
122
|
return function(elem: (idx: number) => A): Collection<A> {
|
|
34
123
|
const res: A[] = new Array<A>(len);
|
|
@@ -39,18 +128,24 @@ export class Collection<T> extends ArrayIterable<T, Collection<T>>
|
|
|
39
128
|
};
|
|
40
129
|
}
|
|
41
130
|
|
|
42
|
-
slice(from: number, until: number): Collection<T> {
|
|
43
|
-
return new Collection<T>(this.items.slice(from, until));
|
|
44
|
-
}
|
|
45
|
-
|
|
46
131
|
map<B>(f: (item: T) => B): Collection<B> {
|
|
47
132
|
return new Collection<B>(this.items.map(i => f(i)));
|
|
48
133
|
}
|
|
49
134
|
|
|
50
135
|
flatMap<B>(f: (item: T) => Collection<B>): Collection<B> {
|
|
51
|
-
|
|
136
|
+
const res: B[] = [];
|
|
137
|
+
this.items.forEach(i => {
|
|
138
|
+
res.push(...f(i).items);
|
|
139
|
+
});
|
|
140
|
+
return new Collection<B>(res);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
flatMapOption<B>(f: (item: T) => Option<B>): Collection<B> {
|
|
144
|
+
const res: B[] = [];
|
|
52
145
|
this.items.forEach(i => {
|
|
53
|
-
|
|
146
|
+
f(i).foreach(v => {
|
|
147
|
+
res.push(v);
|
|
148
|
+
});
|
|
54
149
|
});
|
|
55
150
|
return new Collection<B>(res);
|
|
56
151
|
}
|
|
@@ -86,7 +181,7 @@ export class Collection<T> extends ArrayIterable<T, Collection<T>>
|
|
|
86
181
|
* @param f
|
|
87
182
|
*/
|
|
88
183
|
async mapPromiseAll<B>(f: (v: T) => Promise<B>): Promise<Collection<B>> {
|
|
89
|
-
return new Collection(await Promise.all(this.items.map(i => f(i))));
|
|
184
|
+
return new Collection<B>(await Promise.all(this.items.map(i => f(i))));
|
|
90
185
|
}
|
|
91
186
|
|
|
92
187
|
/**
|
|
@@ -106,10 +201,10 @@ export class Collection<T> extends ArrayIterable<T, Collection<T>>
|
|
|
106
201
|
* @param f
|
|
107
202
|
*/
|
|
108
203
|
async flatMapPromise<B>(f: (item: T) => Promise<Collection<B>>): Promise<Collection<B>> {
|
|
109
|
-
|
|
204
|
+
const res: B[] = [];
|
|
110
205
|
for (let i = 0; i < this.items.length; i++) {
|
|
111
206
|
const item = this.items[i];
|
|
112
|
-
res
|
|
207
|
+
res.push(...(await f(item)).items);
|
|
113
208
|
}
|
|
114
209
|
return new Collection<B>(res);
|
|
115
210
|
}
|
|
@@ -135,79 +230,14 @@ export class Collection<T> extends ArrayIterable<T, Collection<T>>
|
|
|
135
230
|
return new Collection<B>(res);
|
|
136
231
|
}
|
|
137
232
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
return this.items[idx];
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
get toArray(): T[] {
|
|
145
|
-
return this.items;
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
get reverse(): Collection<T> {
|
|
150
|
-
return new Collection(this.items.reverse());
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
sort(param: (a: T, b: T) => number): Collection<T> {
|
|
154
|
-
return new Collection(this.items.sort(param));
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
sortBy(fieldToNumber: (a: T) => number): Collection<T> {
|
|
159
|
-
return this.sort((a, b) => fieldToNumber(a) - fieldToNumber(b));
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
appended(item: T): Collection<T> {
|
|
164
|
-
return new Collection(this.items.concat([item]));
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
appendedAll(other: Collection<T>): Collection<T> {
|
|
168
|
-
return new Collection(this.items.concat(other.items));
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
prepended(item: T): Collection<T> {
|
|
172
|
-
return new Collection([item].concat(this.items));
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
prependedAll(other: Collection<T>): Collection<T> {
|
|
176
|
-
return new Collection(other.items.concat(this.items));
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
concat(other: Collection<T>): Collection<T> {
|
|
180
|
-
return this.appendedAll(other);
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
get toSet(): HashSet<T> {
|
|
184
|
-
return HashSet.of(...this.items);
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
get distinct(): Collection<T> {
|
|
188
|
-
return HashSet.of(...this.items).toCollection;
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
distinctBy(key: (item: T) => string | number): Collection<T> {
|
|
192
|
-
const keys = new Set();
|
|
193
|
-
const res: T[] = [];
|
|
194
|
-
this.foreach(item => {
|
|
195
|
-
const currentKey = key(item);
|
|
196
|
-
if (!keys.has(currentKey)) {
|
|
197
|
-
keys.add(currentKey);
|
|
198
|
-
res.push(item);
|
|
199
|
-
}
|
|
200
|
-
});
|
|
201
|
-
return new Collection<T>(res);
|
|
233
|
+
get toBuffer(): ArrayBuffer<T> {
|
|
234
|
+
return new ArrayBuffer(this.items);
|
|
202
235
|
}
|
|
203
236
|
|
|
204
237
|
toMap<K, V>(mapper: (item: T) => [K, V]): HashMap<K, V> {
|
|
205
238
|
return HashMap.of(...this.map(mapper).toArray);
|
|
206
239
|
}
|
|
207
240
|
|
|
208
|
-
indexOf(item: T): number {
|
|
209
|
-
return this.items.indexOf(item);
|
|
210
|
-
}
|
|
211
241
|
|
|
212
242
|
/** Returns a $coll formed from this $coll and another iterable collection
|
|
213
243
|
* by combining corresponding elements in pairs.
|
|
@@ -255,3 +285,282 @@ export class Collection<T> extends ArrayIterable<T, Collection<T>>
|
|
|
255
285
|
|
|
256
286
|
|
|
257
287
|
export const Nil = Collection.empty;
|
|
288
|
+
|
|
289
|
+
export class ArrayBuffer<T> extends ArrayBackedCollection<T, ArrayBuffer<T>> implements Mappable<T>,
|
|
290
|
+
Filterable<T, ArrayBuffer<T>>{
|
|
291
|
+
|
|
292
|
+
static get empty(): ArrayBuffer<any> {
|
|
293
|
+
return new ArrayBuffer<any>([]);
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
constructor(protected readonly items: T[]) {
|
|
297
|
+
super();
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
static of<T>(...elements: T[]): ArrayBuffer<T> {
|
|
301
|
+
return new ArrayBuffer<T>(elements);
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
static from<T>(elements: Iterable<T>): ArrayBuffer<T> {
|
|
305
|
+
return new ArrayBuffer<T>(Array.from(elements));
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
static fill<A>(len: number): (elem: (idx: number) => A) => ArrayBuffer<A> {
|
|
309
|
+
return function (elem: (idx: number) => A): ArrayBuffer<A> {
|
|
310
|
+
const res: A[] = new Array<A>(len);
|
|
311
|
+
for (let i = 0; i < len; i++) {
|
|
312
|
+
res[i] = elem(i);
|
|
313
|
+
}
|
|
314
|
+
return new ArrayBuffer(res);
|
|
315
|
+
};
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
protected fromArray(array: T[]): ArrayBuffer<T> {
|
|
319
|
+
if (!array || array.length <= 0) {
|
|
320
|
+
return new ArrayBuffer<T>([]);
|
|
321
|
+
} else {
|
|
322
|
+
return new ArrayBuffer(array);
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
|
|
327
|
+
|
|
328
|
+
/** Replaces element at given index with a new value.
|
|
329
|
+
*
|
|
330
|
+
* @param index the index of the element to replace.
|
|
331
|
+
* @param element the new value.
|
|
332
|
+
* @throws Error if the index is not valid.
|
|
333
|
+
*/
|
|
334
|
+
update(index: number, element: T): void {
|
|
335
|
+
this.checkWithinBounds(index, index + 1);
|
|
336
|
+
this.items[index] = element;
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
/** Replaces element at given index with a new value.
|
|
340
|
+
*
|
|
341
|
+
* @param index the index of the element to replace.
|
|
342
|
+
* @param element the new value.
|
|
343
|
+
* @throws Error if the index is not valid.
|
|
344
|
+
*/
|
|
345
|
+
set(index: number, element: T): void {
|
|
346
|
+
this.update(index, element);
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
|
|
350
|
+
/**
|
|
351
|
+
* Clears the buffer's contents. After this operation, the
|
|
352
|
+
* buffer is empty.
|
|
353
|
+
*/
|
|
354
|
+
clear(): void {
|
|
355
|
+
this.items.length = 0;
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
|
|
359
|
+
/**
|
|
360
|
+
* Appends the given elements to this buffer.
|
|
361
|
+
* @param element the element to append.
|
|
362
|
+
* @return the buffer itself
|
|
363
|
+
*/
|
|
364
|
+
append(element: T): this {
|
|
365
|
+
this.items.push(element);
|
|
366
|
+
return this;
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
/**
|
|
370
|
+
* Appends the elements contained in a iterable object to this buffer.
|
|
371
|
+
* @param elements the iterable object containing the elements to append.
|
|
372
|
+
* @return the buffer itself
|
|
373
|
+
*/
|
|
374
|
+
appendAll(elements: Iterable<T>): this {
|
|
375
|
+
this.items.push(...elements);
|
|
376
|
+
return this;
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
/**
|
|
380
|
+
* Prepends a single element at the front of this ArrayBuffer.
|
|
381
|
+
*
|
|
382
|
+
* @param element the element to add.
|
|
383
|
+
* @return the buffer itself
|
|
384
|
+
*/
|
|
385
|
+
prepend(element: T): this {
|
|
386
|
+
this.items.unshift(element);
|
|
387
|
+
return this;
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
prependAll(elements: Iterable<T>): this {
|
|
391
|
+
this.items.unshift(...elements);
|
|
392
|
+
return this;
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
/**
|
|
396
|
+
* Inserts a new element at a given index into this buffer.
|
|
397
|
+
*
|
|
398
|
+
* @param idx the index where the new elements is inserted.
|
|
399
|
+
* @param element the element to insert.
|
|
400
|
+
* @throws Error if the index `idx` is not in the valid range
|
|
401
|
+
* `0 <= idx <= length`.
|
|
402
|
+
*/
|
|
403
|
+
insert(idx: number, element: T): void {
|
|
404
|
+
this.checkWithinBounds(idx, idx);
|
|
405
|
+
this.items.splice(idx, 0, element);
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
/** Inserts new elements at the index `idx`. Opposed to method
|
|
409
|
+
* `update`, this method will not replace an element with a new
|
|
410
|
+
* one. Instead, it will insert a new element at index `idx`.
|
|
411
|
+
*
|
|
412
|
+
* @param idx the index where a new element will be inserted.
|
|
413
|
+
* @param elements the iterable object providing all elements to insert.
|
|
414
|
+
* @throws Error if `idx` is out of bounds.
|
|
415
|
+
*/
|
|
416
|
+
insertAll(idx: number, elements: Iterable<T>): void {
|
|
417
|
+
this.checkWithinBounds(idx, idx);
|
|
418
|
+
this.items.splice(idx, 0, ...elements);
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
/** Removes the element on a given index position.
|
|
422
|
+
*
|
|
423
|
+
* @param index the index which refers to the first element to remove.
|
|
424
|
+
* @param count the number of elements to remove.
|
|
425
|
+
* @throws Error if the index `idx` is not in the valid range
|
|
426
|
+
* `0 <= idx <= length - count` (with `count > 0`).
|
|
427
|
+
* @throws Error if `count < 0`.
|
|
428
|
+
*/
|
|
429
|
+
remove(index: number, count = 1): void {
|
|
430
|
+
if (count > 0) {
|
|
431
|
+
this.checkWithinBounds(index, index + 1);
|
|
432
|
+
this.items.splice(index, count);
|
|
433
|
+
} else if (count < 0) {
|
|
434
|
+
throw new Error('removing negative number of elements: ' + count);
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
/** Removes a single element from this buffer, at its first occurrence.
|
|
439
|
+
* If the buffer does not contain that element, it is unchanged.
|
|
440
|
+
*
|
|
441
|
+
* @param element the element to remove.
|
|
442
|
+
* @return the buffer itself
|
|
443
|
+
*/
|
|
444
|
+
subtractOne(element: T): this {
|
|
445
|
+
const i = this.items.indexOf(element);
|
|
446
|
+
if (i != -1) {
|
|
447
|
+
this.remove(i);
|
|
448
|
+
}
|
|
449
|
+
return this;
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
/** Removes all elements produced by an iterator from this buffer.
|
|
453
|
+
*
|
|
454
|
+
* @param elements the iterator producing the elements to remove.
|
|
455
|
+
* @return the buffer itself
|
|
456
|
+
*/
|
|
457
|
+
subtractAll(elements: Iterable<T>): this {
|
|
458
|
+
if (elements === this || elements === this.items) {
|
|
459
|
+
const buf = new ArrayBuffer(Array.from(elements));
|
|
460
|
+
buf.foreach(e => this.subtractOne(e));
|
|
461
|
+
} else {
|
|
462
|
+
for (const element of elements) {
|
|
463
|
+
this.subtractOne(element);
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
return this;
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
|
|
470
|
+
/**
|
|
471
|
+
* returns same instance
|
|
472
|
+
* @param compareFn
|
|
473
|
+
* @return the buffer itself
|
|
474
|
+
*/
|
|
475
|
+
sort(compareFn?: (a: T, b: T) => number): this {
|
|
476
|
+
this.items.sort(compareFn);
|
|
477
|
+
return this;
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
get toCollection(): Collection<T> {
|
|
481
|
+
return new Collection<T>(this.items.slice(0));
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
|
|
485
|
+
/** Builds a new ArrayBuffer by applying a function to all elements of this ArrayBuffer
|
|
486
|
+
* and using the elements of the resulting collections.
|
|
487
|
+
*
|
|
488
|
+
* For example:
|
|
489
|
+
*
|
|
490
|
+
* {{{
|
|
491
|
+
* getWords(lines: ArrayBuffer<string>): ArrayBuffer<string> {
|
|
492
|
+
* return lines.flatMap(line => ArrayBuffer.from(line.split("\\W+")))
|
|
493
|
+
* }
|
|
494
|
+
* }}}
|
|
495
|
+
*
|
|
496
|
+
*
|
|
497
|
+
* @param f the function to apply to each element.
|
|
498
|
+
* @tparam B the element type of the returned collection.
|
|
499
|
+
* @return a new ArrayBuffer resulting from applying the given collection-valued function
|
|
500
|
+
* `f` to each element of this $coll and concatenating the results.
|
|
501
|
+
*/
|
|
502
|
+
flatMap<B>(f: (item: T) => ArrayBuffer<B>): ArrayBuffer<B> {
|
|
503
|
+
const res: B[] = [];
|
|
504
|
+
this.items.forEach(i => {
|
|
505
|
+
res.push(...f(i).items);
|
|
506
|
+
});
|
|
507
|
+
return new ArrayBuffer<B>(res);
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
flatMapOption<B>(f: (item: T) => Option<B>): ArrayBuffer<B> {
|
|
511
|
+
const res: B[] = [];
|
|
512
|
+
this.items.forEach(i => {
|
|
513
|
+
f(i).foreach(v => {
|
|
514
|
+
res.push(v);
|
|
515
|
+
});
|
|
516
|
+
});
|
|
517
|
+
return new ArrayBuffer<B>(res);
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
|
|
521
|
+
async flatMapPromise<B>(f: (item: T) => Promise<ArrayBuffer<B>>): Promise<ArrayBuffer<B>> {
|
|
522
|
+
const res: B[] = [];
|
|
523
|
+
for (let i = 0; i < this.items.length; i++) {
|
|
524
|
+
const item = this.items[i];
|
|
525
|
+
res.push(...(await f(item)).items);
|
|
526
|
+
}
|
|
527
|
+
return new ArrayBuffer<B>(res);
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
map<B>(f: (item: T) => B): ArrayBuffer<B> {
|
|
531
|
+
return new ArrayBuffer<B>(this.items.map(i => f(i)));
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
async mapPromise<B>(f: (v: T) => Promise<B>): Promise<ArrayBuffer<B>> {
|
|
535
|
+
const res: B[] = [];
|
|
536
|
+
for (let i = 0; i < this.items.length; i++) {
|
|
537
|
+
res.push(await f(this.items[i]));
|
|
538
|
+
}
|
|
539
|
+
return new ArrayBuffer<B>(res);
|
|
540
|
+
}
|
|
541
|
+
|
|
542
|
+
async mapPromiseAll<B>(f: (v: T) => Promise<B>): Promise<ArrayBuffer<B>> {
|
|
543
|
+
return new ArrayBuffer<B>(await Promise.all(this.items.map(i => f(i))));
|
|
544
|
+
}
|
|
545
|
+
|
|
546
|
+
async flatMapPromiseAll<B>(f: (v: T) => Promise<ArrayBuffer<B>>): Promise<ArrayBuffer<B>> {
|
|
547
|
+
return (await this.mapPromiseAll(f)).flatten<B>();
|
|
548
|
+
}
|
|
549
|
+
|
|
550
|
+
flatten<B>(): ArrayBuffer<B> {
|
|
551
|
+
const res: B[] = [];
|
|
552
|
+
this.items.forEach(i => {
|
|
553
|
+
if (i instanceof ArrayBuffer) {
|
|
554
|
+
res.push(...i.items);
|
|
555
|
+
} else {
|
|
556
|
+
res.push(i as any as B);
|
|
557
|
+
}
|
|
558
|
+
});
|
|
559
|
+
return new ArrayBuffer<B>(res);
|
|
560
|
+
}
|
|
561
|
+
|
|
562
|
+
toMap<K, V>(mapper: (item: T) => [K, V]): HashMap<K, V> {
|
|
563
|
+
return HashMap.of(...this.map(mapper).toArray);
|
|
564
|
+
}
|
|
565
|
+
|
|
566
|
+
}
|
package/src/either.ts
CHANGED
|
@@ -305,7 +305,7 @@ export abstract class Either<LEFT, RIGHT> implements Mappable<RIGHT> {
|
|
|
305
305
|
|
|
306
306
|
async mapPromise<RIGHT1>(f: (v: RIGHT) => Promise<RIGHT1>): Promise<Either<LEFT, RIGHT1>> {
|
|
307
307
|
return this.match({
|
|
308
|
-
right: async v => right(await f(v)) as Either<LEFT, RIGHT1>,
|
|
308
|
+
right: async v => right<RIGHT1>(await f(v)) as Either<LEFT, RIGHT1>,
|
|
309
309
|
left: () => Promise.resolve(this as unknown as Either<LEFT, RIGHT1>)
|
|
310
310
|
});
|
|
311
311
|
}
|
|
@@ -438,7 +438,7 @@ export namespace Either {
|
|
|
438
438
|
|
|
439
439
|
mapPromise<A1, B1 extends B>(f: (item: A) => Promise<A1>): Promise<Either<A1, B1>> {
|
|
440
440
|
return this.e.match<Promise<Either<A1, B1>>>({
|
|
441
|
-
left: async v => left(await f(v)),
|
|
441
|
+
left: async v => left<A1>(await f(v)),
|
|
442
442
|
right: () => Promise.resolve(this.e as unknown as Either<A1, B1>)
|
|
443
443
|
}) as Promise<Either<A1, B1>>;
|
|
444
444
|
}
|