@zwa73/utils 1.0.60 → 1.0.62
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/UtilCodecs.d.ts +16 -16
- package/dist/UtilCodecs.js +16 -16
- package/dist/UtilCom.d.ts +22 -25
- package/dist/UtilCom.js +35 -38
- package/dist/UtilDecorators.d.ts +15 -8
- package/dist/UtilDecorators.js +79 -25
- package/dist/UtilFP.d.ts +46 -0
- package/dist/UtilFP.js +52 -0
- package/dist/UtilFfmpegTools.d.ts +30 -30
- package/dist/UtilFfmpegTools.js +32 -32
- package/dist/UtilFileTools.d.ts +30 -35
- package/dist/UtilFileTools.js +17 -18
- package/dist/UtilFunctions.d.ts +37 -78
- package/dist/UtilFunctions.js +27 -62
- package/dist/UtilInterfaces.d.ts +26 -11
- package/dist/UtilInterfaces.js +12 -3
- package/dist/UtilLogger.d.ts +55 -55
- package/dist/UtilLogger.js +55 -55
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/test/composeTest.d.ts +26 -0
- package/dist/test/composeTest.js +50 -0
- package/dist/test/importtest.d.ts +1 -0
- package/dist/test/importtest.js +4 -0
- package/dist/test/test.js +5 -3
- package/package.json +1 -1
- package/src/UtilClass.ts +1051 -1051
- package/src/UtilCodecs.ts +117 -117
- package/src/UtilCom.ts +171 -174
- package/src/UtilDecorators.ts +174 -116
- package/src/UtilFP.ts +98 -0
- package/src/UtilFfmpegTools.ts +271 -271
- package/src/UtilFileTools.ts +231 -236
- package/src/UtilFunctions.ts +289 -364
- package/src/UtilInterfaces.ts +158 -138
- package/src/UtilLogger.ts +386 -386
- package/src/index.ts +10 -9
- package/src/test/composeTest.ts +50 -0
- package/src/test/importtest.ts +5 -0
- package/src/test/test.ts +8 -6
- package/src/test/test2.ts +2 -3
- package/tsconfig.json +2 -7
package/src/UtilClass.ts
CHANGED
|
@@ -1,1051 +1,1051 @@
|
|
|
1
|
-
type struct = number | string;
|
|
2
|
-
|
|
3
|
-
/**遍历函数
|
|
4
|
-
*/
|
|
5
|
-
interface EachCallback<T> {
|
|
6
|
-
/**
|
|
7
|
-
* @param {T} value - 值
|
|
8
|
-
* @param {number} index - 下标
|
|
9
|
-
* @param {SList<T>} list - 数组
|
|
10
|
-
* @returns {void}
|
|
11
|
-
*/
|
|
12
|
-
(value: T, index: number, list: SList<T>): void;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
/**加工函数
|
|
16
|
-
*/
|
|
17
|
-
interface MapCallback<T, U> {
|
|
18
|
-
/**
|
|
19
|
-
* @param {T} value - 值
|
|
20
|
-
* @param {number} index - 下标
|
|
21
|
-
* @param {SList<T>} list - 数组
|
|
22
|
-
* @returns {U} - 返回值
|
|
23
|
-
*/
|
|
24
|
-
(value: T, index: number, list: SList<T>): U;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
/**过滤函数
|
|
28
|
-
*/
|
|
29
|
-
interface FiltCallback<T> {
|
|
30
|
-
/**
|
|
31
|
-
* @param {T} value - 值
|
|
32
|
-
* @param {number} index - 下标
|
|
33
|
-
* @param {SList<T>} list - 数组
|
|
34
|
-
* @returns {boolean} - 返回值
|
|
35
|
-
*/
|
|
36
|
-
(value: T, index: number, list: SList<T>): boolean;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
/**统计函数
|
|
40
|
-
*/
|
|
41
|
-
interface AggrCallback<T, U> {
|
|
42
|
-
/**
|
|
43
|
-
* @param {U} accumulator - 累加器
|
|
44
|
-
* @param {T} value - 值
|
|
45
|
-
* @param {number} index - 下标
|
|
46
|
-
* @param {SList<T>} list - 数组
|
|
47
|
-
* @returns {U} - 返回值
|
|
48
|
-
*/
|
|
49
|
-
(accumulator: U, value: T, index: number, list: SList<T>): U;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
/**缩减函数
|
|
53
|
-
*/
|
|
54
|
-
interface ReduceCallback<T> {
|
|
55
|
-
/**
|
|
56
|
-
* @param {T} previousValue - 上一个值/累加值
|
|
57
|
-
* @param {T} currentValue - 当前值
|
|
58
|
-
* @param {number} currentIndex - 当前下标
|
|
59
|
-
* @param {SList<T>} list - 数组
|
|
60
|
-
* @returns {T} - 返回值
|
|
61
|
-
*/
|
|
62
|
-
(
|
|
63
|
-
previousValue: T,
|
|
64
|
-
currentValue: T,
|
|
65
|
-
currentIndex: number,
|
|
66
|
-
list: SList<T>
|
|
67
|
-
): T;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
/**排序函数
|
|
71
|
-
*/
|
|
72
|
-
interface SortCallback<T> {
|
|
73
|
-
/**
|
|
74
|
-
* @param {T} a - 值a
|
|
75
|
-
* @param {T} b - 值b
|
|
76
|
-
* @returns {number} - 返回值
|
|
77
|
-
*/
|
|
78
|
-
(a: T, b: T): number;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
export class SList<T> {
|
|
82
|
-
private _arr: Array<T>;
|
|
83
|
-
/**建立0长度的SList */
|
|
84
|
-
constructor();
|
|
85
|
-
/**建立一个长度为 obj 的SList */
|
|
86
|
-
constructor(obj:number);
|
|
87
|
-
/**根据obj建立SList */
|
|
88
|
-
constructor(obj:Array<T>);
|
|
89
|
-
constructor(obj?: Array<T> | number) {
|
|
90
|
-
if (typeof obj == "number") this._arr = new Array<T>(obj);
|
|
91
|
-
else if (Array.isArray(obj)) this._arr = obj;
|
|
92
|
-
else this._arr = [];
|
|
93
|
-
}
|
|
94
|
-
/**返回数组长度
|
|
95
|
-
* @returns {number} - 长度
|
|
96
|
-
*/
|
|
97
|
-
size(): number {
|
|
98
|
-
return this._arr.length;
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
/**获取指定下标的元素
|
|
102
|
-
* @param {number} index - 下标
|
|
103
|
-
* @returns {T} - 目标元素
|
|
104
|
-
*/
|
|
105
|
-
get(index: number): T {
|
|
106
|
-
return this._arr[index];
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
/**设置指定下标的元素
|
|
110
|
-
* 返回自身 改变自身
|
|
111
|
-
* @param {number} index - 下标
|
|
112
|
-
* @param {T} value - 值
|
|
113
|
-
* @returns {SList<T>} - 自身
|
|
114
|
-
*/
|
|
115
|
-
set(index: number, value: T): SList<T> {
|
|
116
|
-
this._arr[index] = value;
|
|
117
|
-
return this;
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
/**连接两个数组
|
|
121
|
-
* @param {SList<T>} list - 目标数组
|
|
122
|
-
* @returns {SList<T>} - 新数组
|
|
123
|
-
*/
|
|
124
|
-
concat(list: SList<T>): SList<T> {
|
|
125
|
-
return new SList<T>(this._arr.concat(list._arr));
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
/**在数组末尾添加一个元素
|
|
129
|
-
* 返回自身 改变自身
|
|
130
|
-
* @param {T} value - 值
|
|
131
|
-
* @returns {SList<T>} - 自身
|
|
132
|
-
*/
|
|
133
|
-
push(value: T): SList<T> {
|
|
134
|
-
this._arr.push(value);
|
|
135
|
-
return this;
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
/**在数组末尾添加一个数组
|
|
139
|
-
* 改变自身
|
|
140
|
-
* @param {SList<T>} list - 目标数组
|
|
141
|
-
* @returns {SList<T>} - 自身
|
|
142
|
-
*/
|
|
143
|
-
pushList(list: SList<T>) {
|
|
144
|
-
this._arr = this._arr.concat(list._arr);
|
|
145
|
-
return this;
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
/**截取从起始点到结束点之前的一段数组
|
|
149
|
-
* @param {number} strat - 起始点
|
|
150
|
-
* @param {number} end - 结束点
|
|
151
|
-
* @returns {SList<T>} - 新数组
|
|
152
|
-
*/
|
|
153
|
-
slice(strat: number, end: number): SList<T> {
|
|
154
|
-
return new SList(this._arr.slice(strat, end));
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
/**翻转数组
|
|
158
|
-
* 改变自身
|
|
159
|
-
* @returns {SList<T>} - 自身
|
|
160
|
-
*/
|
|
161
|
-
reverse(): SList<T> {
|
|
162
|
-
this._arr.reverse();
|
|
163
|
-
return this;
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
/**将SList转换为数组
|
|
167
|
-
* @returns {Array<T>} - 数组
|
|
168
|
-
*/
|
|
169
|
-
toArray(): Array<T> {
|
|
170
|
-
return ([] as T[]).concat(this._arr);
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
/**将SList转换为SStream
|
|
174
|
-
* @param {number} concurrent - 并发数
|
|
175
|
-
* @returns {SStream<T>} - 流
|
|
176
|
-
*/
|
|
177
|
-
toSStream(concurrent?: number): SStream<T> {
|
|
178
|
-
return new SStream<T>(this._arr, concurrent);
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
/**返回指定元素在数组中首次出现的位置
|
|
182
|
-
* @param {T} value - 目标元素
|
|
183
|
-
* @returns {number} - 下标
|
|
184
|
-
*/
|
|
185
|
-
indexOf(value: T): number {
|
|
186
|
-
return this._arr.indexOf(value);
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
/**返回指定元素在数组中最后一次出现的位置
|
|
190
|
-
* @param {T} value - 目标元素
|
|
191
|
-
* @returns {number} - 下标
|
|
192
|
-
*/
|
|
193
|
-
lastIndexOf(value: T): number {
|
|
194
|
-
return this._arr.lastIndexOf(value);
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
/**判断数组中是否包含指定元素
|
|
198
|
-
* @param {T} value - 目标元素
|
|
199
|
-
* @returns {boolean} - 是否包含
|
|
200
|
-
*/
|
|
201
|
-
contains(value: T): boolean {
|
|
202
|
-
return this._arr.includes(value);
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
/**获取迭代器
|
|
206
|
-
* @returns {SIterator<T>} - 迭代器
|
|
207
|
-
*/
|
|
208
|
-
iterator(): SIterator<T> {
|
|
209
|
-
return new SIterator<T>(this);
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
/**平分数组
|
|
213
|
-
* @param {number} count - 份数
|
|
214
|
-
* @param {"average" | "chunk"} mode - 模式 average:轮询平均分 chunk:切块均分
|
|
215
|
-
* @returns {SList<SList<T>>} - 新数组
|
|
216
|
-
*/
|
|
217
|
-
divide(
|
|
218
|
-
count: number,
|
|
219
|
-
mode: "average" | "chunk" = "average"
|
|
220
|
-
): SList<SList<T>> {
|
|
221
|
-
if (count <= 0) return new SList<SList<T>>();
|
|
222
|
-
if (count == 1) return new SList<SList<T>>([this.clone()]);
|
|
223
|
-
|
|
224
|
-
let result = new SList<SList<T>>();
|
|
225
|
-
switch (mode) {
|
|
226
|
-
//轮询平均分
|
|
227
|
-
default:
|
|
228
|
-
case "average":
|
|
229
|
-
for (let i = 0; i < count; i++) {
|
|
230
|
-
let clist = new SList<T>();
|
|
231
|
-
let size = this.size();
|
|
232
|
-
for (let j = i; j < size; j += count)
|
|
233
|
-
clist.push(this.get(j));
|
|
234
|
-
result.push(clist);
|
|
235
|
-
}
|
|
236
|
-
break;
|
|
237
|
-
//切块均分
|
|
238
|
-
case "chunk":
|
|
239
|
-
let chunkSize = Math.ceil(this.size() / count);
|
|
240
|
-
for (let i = 0; i < count; i++) {
|
|
241
|
-
let start = i * chunkSize;
|
|
242
|
-
let end = (i + 1) * chunkSize;
|
|
243
|
-
if (end > this.size()) end = this.size();
|
|
244
|
-
result.push(this.slice(start, end));
|
|
245
|
-
}
|
|
246
|
-
break;
|
|
247
|
-
}
|
|
248
|
-
return result;
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
/**从index开始删除count个元素,返回删除的元素数组
|
|
252
|
-
* 改变自身
|
|
253
|
-
* @param {number} index - 起始点
|
|
254
|
-
* @param {number} count - 数量
|
|
255
|
-
* @returns {SList<T>} - 删除的元素数组
|
|
256
|
-
*/
|
|
257
|
-
removeRange(index: number, count: number): SList<T> {
|
|
258
|
-
let narr = this._arr.splice(index, count);
|
|
259
|
-
return new SList<T>(narr);
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
/**删除对应下标下的元素,返回删除的元素
|
|
263
|
-
* 改变自身
|
|
264
|
-
* @param {number} i - 下标
|
|
265
|
-
* @returns {T|null} - 删除的元素
|
|
266
|
-
*/
|
|
267
|
-
remove(i: number): T|null {
|
|
268
|
-
if (i >= 0 && i < this.size())
|
|
269
|
-
return this._arr.splice(i, 1)[0];
|
|
270
|
-
return null;
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
/**删除第一个匹配的项目,返回自身
|
|
274
|
-
* 改变自身
|
|
275
|
-
* @param {T} obj - 需删除目标
|
|
276
|
-
* @returns {SList<T>} - 自身
|
|
277
|
-
*/
|
|
278
|
-
removeMember(obj: T): SList<T> {
|
|
279
|
-
let index = this.indexOf(obj);
|
|
280
|
-
if (index > -1) this.remove(index);
|
|
281
|
-
return this;
|
|
282
|
-
}
|
|
283
|
-
|
|
284
|
-
/**删除所有匹配的项目
|
|
285
|
-
* 改变自身
|
|
286
|
-
* @param {T} obj - 需删除目标
|
|
287
|
-
* @returns {SList<T>} - 自身
|
|
288
|
-
*/
|
|
289
|
-
removeAllMember(obj: T): SList<T> {
|
|
290
|
-
while (this.contains(obj)) this.removeMember(obj);
|
|
291
|
-
return this;
|
|
292
|
-
}
|
|
293
|
-
/**在这个下标对应的元素前添加一个元素
|
|
294
|
-
* 改变自身
|
|
295
|
-
* @param {number} index - 下标
|
|
296
|
-
* @param {T} obj - 添加对象
|
|
297
|
-
* @returns {SList<T>} - 自身
|
|
298
|
-
*/
|
|
299
|
-
insert(index: number, obj: T): SList<T> {
|
|
300
|
-
this._arr.splice(index, 0, obj);
|
|
301
|
-
return this;
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
/**在这个下标对应的元素前添加一组元素
|
|
305
|
-
* 改变自身
|
|
306
|
-
* @param {number} index - 下标
|
|
307
|
-
* @param {SList<T>} obj - 添加对象
|
|
308
|
-
* @returns {SList<T>} - 自身
|
|
309
|
-
*/
|
|
310
|
-
insertRange(index: number, obj: SList<T>): SList<T> {
|
|
311
|
-
this._arr.splice(index, 0, ...obj._arr);
|
|
312
|
-
return this;
|
|
313
|
-
}
|
|
314
|
-
|
|
315
|
-
/**删除并返回最后一个元素
|
|
316
|
-
* 改变自身
|
|
317
|
-
* @returns {T | null} - 最后一个元素
|
|
318
|
-
*/
|
|
319
|
-
pop(): T | null {
|
|
320
|
-
let val = this._arr.pop();
|
|
321
|
-
return val == undefined ? null : val;
|
|
322
|
-
}
|
|
323
|
-
|
|
324
|
-
/**删除并返回第一个元素
|
|
325
|
-
* 改变自身
|
|
326
|
-
* @returns {T | null} - 第一个元素
|
|
327
|
-
*/
|
|
328
|
-
shift(): T | null {
|
|
329
|
-
let val = this._arr.shift();
|
|
330
|
-
return val == undefined ? null : val;
|
|
331
|
-
}
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
/**克隆数组
|
|
336
|
-
* @returns {SList<T>} - 新数组
|
|
337
|
-
*/
|
|
338
|
-
clone(): SList<T> {
|
|
339
|
-
return new SList(([] as T[]).concat(this._arr));
|
|
340
|
-
}
|
|
341
|
-
|
|
342
|
-
/**判断数组是否为空
|
|
343
|
-
* @returns {boolean} - 是否为空
|
|
344
|
-
*/
|
|
345
|
-
isEmpty(): boolean {
|
|
346
|
-
return this.size() == 0;
|
|
347
|
-
}
|
|
348
|
-
|
|
349
|
-
/**删除数组中的重复元素
|
|
350
|
-
* 改变自身
|
|
351
|
-
* @returns {SList<T>} - 自身
|
|
352
|
-
*/
|
|
353
|
-
removeDuplicates(): SList<T> {
|
|
354
|
-
this._arr = Array.from(new Set(this._arr));
|
|
355
|
-
return this;
|
|
356
|
-
}
|
|
357
|
-
|
|
358
|
-
/**交集
|
|
359
|
-
* @param {SList<T>[]} lists - 数组列表
|
|
360
|
-
* @returns {SList<T>} - 新数组
|
|
361
|
-
*/
|
|
362
|
-
intersection(...lists: SList<T>[]): SList<T> {
|
|
363
|
-
let nlist = this.clone().removeDuplicates();
|
|
364
|
-
|
|
365
|
-
for (let list of lists) nlist = list.filt((val) => nlist.contains(val));
|
|
366
|
-
|
|
367
|
-
return nlist;
|
|
368
|
-
}
|
|
369
|
-
/**并集
|
|
370
|
-
* @param {SList<T>[]} lists - 数组列表
|
|
371
|
-
* @returns {SList<T>} - 新数组
|
|
372
|
-
*/
|
|
373
|
-
union(...lists: SList<T>[]): SList<T> {
|
|
374
|
-
let nlist = this.clone().removeDuplicates();
|
|
375
|
-
|
|
376
|
-
for (let list of lists) {
|
|
377
|
-
list.each((val) => {
|
|
378
|
-
if (!nlist.contains(val)) nlist.push(val);
|
|
379
|
-
});
|
|
380
|
-
}
|
|
381
|
-
|
|
382
|
-
return nlist;
|
|
383
|
-
}
|
|
384
|
-
|
|
385
|
-
/**返回符合条件的成员组成的新数组
|
|
386
|
-
* @param {FiltCallback<T>} func - 条件函数
|
|
387
|
-
* @returns {SList<T>} - 新数组
|
|
388
|
-
*/
|
|
389
|
-
filt(func: FiltCallback<T>): SList<T> {
|
|
390
|
-
let nlist = new SList<T>(this.size());
|
|
391
|
-
let length = 0;
|
|
392
|
-
let it = this.iterator();
|
|
393
|
-
while (it.hasNext()) {
|
|
394
|
-
let tmpObj = it.next();
|
|
395
|
-
if (func(tmpObj, it.currIndex(), this)) {
|
|
396
|
-
nlist.set(length, tmpObj);
|
|
397
|
-
length++;
|
|
398
|
-
}
|
|
399
|
-
}
|
|
400
|
-
return nlist.slice(0, length);
|
|
401
|
-
}
|
|
402
|
-
|
|
403
|
-
/**遍历数组的每一个元素
|
|
404
|
-
* @param {EachCallback<T>} func - 遍历函数 (value: T, index: number, list: SList<T>): void
|
|
405
|
-
* @returns {SList<T>} - 自身
|
|
406
|
-
*/
|
|
407
|
-
each(func: EachCallback<T>): SList<T> {
|
|
408
|
-
let it = this.iterator();
|
|
409
|
-
while (it.hasNext()) func(it.next(), it.currIndex(), this);
|
|
410
|
-
return this;
|
|
411
|
-
}
|
|
412
|
-
|
|
413
|
-
/**对数组的每一个元素进行加工,返回加工完成的成员组成的新数组
|
|
414
|
-
* @param {MapCallback<T,O>} func - 加工函数 (value: T, index: number, list: SList<T>): O
|
|
415
|
-
* @returns {SList<O>} - 新数组
|
|
416
|
-
*/
|
|
417
|
-
map<O>(func: MapCallback<T, O>): SList<O> {
|
|
418
|
-
let nlist = new SList<O>(this.size());
|
|
419
|
-
let it = this.iterator();
|
|
420
|
-
while (it.hasNext())
|
|
421
|
-
nlist.set(it.nextIndex(), func(it.next(), it.currIndex(), this));
|
|
422
|
-
return nlist;
|
|
423
|
-
}
|
|
424
|
-
|
|
425
|
-
/**对数组进行排序
|
|
426
|
-
* 如函数返回值大于 0 则将 x 排在 y 后面,小于 0 则将 x 排在 y 前面
|
|
427
|
-
* 改变自身
|
|
428
|
-
* @param {SortCallback<T>} func - 排序函数 (a: T, b: T): number
|
|
429
|
-
* @returns {SList<T>} - 自身
|
|
430
|
-
*/
|
|
431
|
-
sort(func: SortCallback<T>): SList<T> {
|
|
432
|
-
this._arr.sort(func);
|
|
433
|
-
return this;
|
|
434
|
-
}
|
|
435
|
-
/**对数组进行统计 aggregate
|
|
436
|
-
* 遍历数组,并将每次遍历的结果与下一次遍历的元素一起传入函数,最后返回最后一次遍历的结果
|
|
437
|
-
* @param {O} init - 初始值
|
|
438
|
-
* @param {AggrCallback<T,O>} func - 统计函数 (value: T, accumulator: U, index: number, list: SList<T>): U
|
|
439
|
-
* @returns {O} - 统计结果
|
|
440
|
-
*/
|
|
441
|
-
public aggr<O>(init: O, func: AggrCallback<T, O>): O {
|
|
442
|
-
let it = this.iterator();
|
|
443
|
-
let tmpObj = init;
|
|
444
|
-
while (it.hasNext())
|
|
445
|
-
tmpObj = func(tmpObj, it.next(), it.currIndex(), this);
|
|
446
|
-
return tmpObj;
|
|
447
|
-
}
|
|
448
|
-
|
|
449
|
-
/**对数组进行缩减
|
|
450
|
-
* 遍历数组,并将每次遍历的结果与下一次遍历的元素一起传入函数,最后返回最后一次遍历的结果
|
|
451
|
-
* @param {ReduceCallback<T>} func - 缩减函数 (previousValue: T, currentValue: T, currentIndex: number, array: SList<T>):T
|
|
452
|
-
* @param {T} init - 初始值
|
|
453
|
-
* @returns {T} - 缩减结果
|
|
454
|
-
*/
|
|
455
|
-
public reduce(func: ReduceCallback<T>, init?: T): T | null {
|
|
456
|
-
if (this.size() === 0) return null;
|
|
457
|
-
let it = this.iterator();
|
|
458
|
-
let tmpObj = init === undefined ? it.next() : init;
|
|
459
|
-
while (it.hasNext())
|
|
460
|
-
tmpObj = func(tmpObj, it.next(), it.currIndex(), this);
|
|
461
|
-
return tmpObj;
|
|
462
|
-
}
|
|
463
|
-
|
|
464
|
-
//重载TypeScript操作符
|
|
465
|
-
[Symbol.iterator]() {
|
|
466
|
-
let it = this.iterator();
|
|
467
|
-
|
|
468
|
-
return {
|
|
469
|
-
next(): { value: T | null; done: boolean } {
|
|
470
|
-
if (it.hasNext()) {
|
|
471
|
-
return { value: it.next(), done: false };
|
|
472
|
-
} else {
|
|
473
|
-
return { value: null, done: true };
|
|
474
|
-
}
|
|
475
|
-
},
|
|
476
|
-
};
|
|
477
|
-
}
|
|
478
|
-
}
|
|
479
|
-
|
|
480
|
-
interface SStreamOperation<T, U> {
|
|
481
|
-
(item: T): Promise<U>;
|
|
482
|
-
}
|
|
483
|
-
export class SStream<T> {
|
|
484
|
-
/**并发数*/
|
|
485
|
-
private _concurrent: number;
|
|
486
|
-
/**原始列表*/
|
|
487
|
-
private _slist: SList<T>;
|
|
488
|
-
/**加工函数列表*/
|
|
489
|
-
private _operation: Array<SStreamOperation<T, T>> = [];
|
|
490
|
-
constructor(slist: SList<T> | Array<T>, concurrent: number = 1) {
|
|
491
|
-
if (slist instanceof SList) this._slist = slist;
|
|
492
|
-
else if (Array.isArray(slist)) this._slist = new SList(slist);
|
|
493
|
-
else this._slist = new SList();
|
|
494
|
-
this._concurrent = concurrent;
|
|
495
|
-
}
|
|
496
|
-
|
|
497
|
-
/**映射加工
|
|
498
|
-
* @param {SStreamOperation<T,U>} operation - 加工函数
|
|
499
|
-
* @returns {SStream<U>} - 新流
|
|
500
|
-
*/
|
|
501
|
-
map<U>(operation: SStreamOperation<T, U>): SStream<U> {
|
|
502
|
-
this._operation.push(operation as any);
|
|
503
|
-
return this as any as SStream<U>;
|
|
504
|
-
}
|
|
505
|
-
/**遍历
|
|
506
|
-
* 返回自身
|
|
507
|
-
* @param {SStreamOperation<T,void>} operation - 遍历函数
|
|
508
|
-
* @returns {SStream<T>} - 自身
|
|
509
|
-
*/
|
|
510
|
-
each(operation: SStreamOperation<T, void>): SStream<T> {
|
|
511
|
-
let opera = async (item: T) => {
|
|
512
|
-
operation(item);
|
|
513
|
-
return item;
|
|
514
|
-
};
|
|
515
|
-
this._operation.push(opera);
|
|
516
|
-
return this;
|
|
517
|
-
}
|
|
518
|
-
|
|
519
|
-
//终结操作
|
|
520
|
-
/**应用加工
|
|
521
|
-
* @returns {SStream<T>} - 自身
|
|
522
|
-
*/
|
|
523
|
-
async appendOperations(): Promise<SStream<T>> {
|
|
524
|
-
if (this._operation.length == 0) return this;
|
|
525
|
-
|
|
526
|
-
let nlist = new SList<SList<T>>();
|
|
527
|
-
let promiseList: Array<Promise<any>> = [];
|
|
528
|
-
//均分处理
|
|
529
|
-
let sliceList = this._slist.divide(this._concurrent);
|
|
530
|
-
for (let i = 0; i < this._concurrent; i++) {
|
|
531
|
-
let subList = sliceList.get(i);
|
|
532
|
-
if (!subList) continue;
|
|
533
|
-
promiseList.push(
|
|
534
|
-
new Promise(async () => {
|
|
535
|
-
let result = new SList<T>();
|
|
536
|
-
for (let item of subList) {
|
|
537
|
-
if (!item) continue;
|
|
538
|
-
for (let operation of this._operation)
|
|
539
|
-
item = await operation(item);
|
|
540
|
-
result.push(item);
|
|
541
|
-
}
|
|
542
|
-
nlist.set(i, result);
|
|
543
|
-
})
|
|
544
|
-
);
|
|
545
|
-
}
|
|
546
|
-
await Promise.all(promiseList);
|
|
547
|
-
//拼接结果 轮询均分
|
|
548
|
-
let result = new SList<T>(this._slist.size());
|
|
549
|
-
for (let i = 0; i < this._concurrent; i++) {
|
|
550
|
-
let subList = nlist.get(i);
|
|
551
|
-
if (!subList) continue;
|
|
552
|
-
let subSize = subList.size();
|
|
553
|
-
for (let j = 0; j < subSize; j++)
|
|
554
|
-
result.set(i + j * this._concurrent, subList.get(j));
|
|
555
|
-
}
|
|
556
|
-
this._slist = result;
|
|
557
|
-
this._operation = [];
|
|
558
|
-
return this;
|
|
559
|
-
}
|
|
560
|
-
/**转换为SList
|
|
561
|
-
* @returns {SList<T>} - 数组
|
|
562
|
-
*/
|
|
563
|
-
async toSList(): Promise<SList<T>> {
|
|
564
|
-
await this.appendOperations();
|
|
565
|
-
return this._slist;
|
|
566
|
-
}
|
|
567
|
-
/**转换为数组
|
|
568
|
-
* @returns {Array<T>} - 数组
|
|
569
|
-
*/
|
|
570
|
-
async toArray(): Promise<Array<T>> {
|
|
571
|
-
await this.appendOperations();
|
|
572
|
-
return this._slist.toArray();
|
|
573
|
-
}
|
|
574
|
-
}
|
|
575
|
-
|
|
576
|
-
export class SIterator<T> {
|
|
577
|
-
private _index = -1;
|
|
578
|
-
private _list: SList<T>;
|
|
579
|
-
constructor(list: SList<T>) {
|
|
580
|
-
this._list = list;
|
|
581
|
-
}
|
|
582
|
-
/**判断还有没有下一个元素
|
|
583
|
-
* @returns {boolean} - 是否有下一个元素
|
|
584
|
-
*/
|
|
585
|
-
hasNext(): boolean {
|
|
586
|
-
return this._index < this.size() - 1 && this._index >= -1;
|
|
587
|
-
}
|
|
588
|
-
|
|
589
|
-
/**判断当前下标有无元素
|
|
590
|
-
* @returns {boolean} - 是否有当前元素
|
|
591
|
-
*/
|
|
592
|
-
hasCurr(): boolean {
|
|
593
|
-
return this._index < this.size() && this._index >= 0;
|
|
594
|
-
}
|
|
595
|
-
|
|
596
|
-
/**判断还有没有上一个元素
|
|
597
|
-
* @returns {boolean} - 是否有上一个元素
|
|
598
|
-
*/
|
|
599
|
-
hasPre(): boolean {
|
|
600
|
-
return this._index < this.size() + 1 && this._index >= 1;
|
|
601
|
-
}
|
|
602
|
-
|
|
603
|
-
/**返回下一个下标指向的数组内成员,然后下标自加1
|
|
604
|
-
* @returns {T} - 下一个成员
|
|
605
|
-
*/
|
|
606
|
-
next(): T {
|
|
607
|
-
if (this.hasNext()) return this._list.get(++this._index);
|
|
608
|
-
else
|
|
609
|
-
throw "一个 SIterator 迭代器的 next 函数出错,可能是在下标到底时还在尝试迭代";
|
|
610
|
-
}
|
|
611
|
-
|
|
612
|
-
/**返回上一个下标指向的数组内成员,然后下标自减1
|
|
613
|
-
* @returns {T} - 上一个成员
|
|
614
|
-
*/
|
|
615
|
-
pre(): T {
|
|
616
|
-
if (this.hasPre()) return this._list.get(--this._index);
|
|
617
|
-
else
|
|
618
|
-
throw "一个 SIterator 迭代器的 pre 函数出错,可能是在下标小于1时还在尝试迭代";
|
|
619
|
-
}
|
|
620
|
-
|
|
621
|
-
/**返回当前下标指向的数组内成员
|
|
622
|
-
* @returns {T} - 当前成员
|
|
623
|
-
*/
|
|
624
|
-
curr(): T {
|
|
625
|
-
if (this.hasCurr()) return this._list.get(this._index);
|
|
626
|
-
else
|
|
627
|
-
throw "一个 SIterator 迭代器的 curr 函数出错,可能是当前下标不包含元素/当前下标已越界";
|
|
628
|
-
}
|
|
629
|
-
|
|
630
|
-
/**返回遍历长度
|
|
631
|
-
* @returns {number} - 遍历长度
|
|
632
|
-
*/
|
|
633
|
-
size(): number {
|
|
634
|
-
return this._list.size();
|
|
635
|
-
}
|
|
636
|
-
|
|
637
|
-
/**获取下个下标
|
|
638
|
-
* @returns {number} - 下个下标
|
|
639
|
-
*/
|
|
640
|
-
nextIndex(): number {
|
|
641
|
-
return this._index + 1;
|
|
642
|
-
}
|
|
643
|
-
|
|
644
|
-
/**获取当前下标
|
|
645
|
-
* @return {number} - 当前下标
|
|
646
|
-
*/
|
|
647
|
-
currIndex(): number {
|
|
648
|
-
return this._index;
|
|
649
|
-
}
|
|
650
|
-
|
|
651
|
-
/**获取上个下标
|
|
652
|
-
* @returns {number} - 上个下标
|
|
653
|
-
*/
|
|
654
|
-
preIndex(): number {
|
|
655
|
-
return this._index - 1;
|
|
656
|
-
}
|
|
657
|
-
|
|
658
|
-
/**判断是否是最后一个
|
|
659
|
-
* @returns {boolean} - 是否是最后一个
|
|
660
|
-
*/
|
|
661
|
-
isLast(): boolean {
|
|
662
|
-
return this._index >= this._list.size() - 1;
|
|
663
|
-
}
|
|
664
|
-
|
|
665
|
-
/**设置数组在迭代器当前下标中的内容
|
|
666
|
-
* 返回自身
|
|
667
|
-
* @param {T} val 要设置的内容
|
|
668
|
-
* @returns {void}
|
|
669
|
-
*/
|
|
670
|
-
set(val: T): SIterator<T> {
|
|
671
|
-
this._list.set(this._index, val);
|
|
672
|
-
return this;
|
|
673
|
-
}
|
|
674
|
-
|
|
675
|
-
/**删除数组在当前下标的内容,然后将下标移至上一位,改变数组长度
|
|
676
|
-
* @returns {T} - 被删除的内容
|
|
677
|
-
*/
|
|
678
|
-
remove(): T {
|
|
679
|
-
let tmp = this._list.get(this._index);
|
|
680
|
-
this._list.remove(this._index);
|
|
681
|
-
this._index--;
|
|
682
|
-
return tmp;
|
|
683
|
-
}
|
|
684
|
-
|
|
685
|
-
/**在当前下标前插入元素,然后将下标移至原元素,即下一位,改变数组长度
|
|
686
|
-
* 返回自身
|
|
687
|
-
* @param {T} obj - 要插入的元素
|
|
688
|
-
* @returns {SIterator<T>} - 自身
|
|
689
|
-
*/
|
|
690
|
-
addPre(obj: T): SIterator<T> {
|
|
691
|
-
this._list.insert(this._index, obj);
|
|
692
|
-
this._index++;
|
|
693
|
-
return this;
|
|
694
|
-
}
|
|
695
|
-
|
|
696
|
-
/**在当前下标后插入元素,然后将下标移至新元素,即下一位,改变数组长度
|
|
697
|
-
* 返回自身
|
|
698
|
-
* @param {T} obj - 要插入的元素
|
|
699
|
-
* @returns {SIterator<T>} - 自身
|
|
700
|
-
*/
|
|
701
|
-
addNext(obj: T): SIterator<T> {
|
|
702
|
-
this._list.insert(this._index + 1, obj);
|
|
703
|
-
this._index++;
|
|
704
|
-
return this;
|
|
705
|
-
}
|
|
706
|
-
}
|
|
707
|
-
|
|
708
|
-
export class SEntry<K, V> {
|
|
709
|
-
private _key: K;
|
|
710
|
-
private _value: V;
|
|
711
|
-
|
|
712
|
-
constructor(key: K, value: V) {
|
|
713
|
-
this._key = key;
|
|
714
|
-
this._value = value;
|
|
715
|
-
}
|
|
716
|
-
getKey() {
|
|
717
|
-
return this._key;
|
|
718
|
-
}
|
|
719
|
-
getValue() {
|
|
720
|
-
return this._value;
|
|
721
|
-
}
|
|
722
|
-
|
|
723
|
-
//重载TypeScript操作符
|
|
724
|
-
get key(): K {
|
|
725
|
-
return this.getKey();
|
|
726
|
-
}
|
|
727
|
-
|
|
728
|
-
get value(): V {
|
|
729
|
-
return this._value;
|
|
730
|
-
}
|
|
731
|
-
}
|
|
732
|
-
export class SHashMap<K, V> {
|
|
733
|
-
private _map: Map<K, V> = new Map();
|
|
734
|
-
|
|
735
|
-
/**构造函数
|
|
736
|
-
* @param {Map<K, V>} [map] - 一个键值对集合
|
|
737
|
-
*/
|
|
738
|
-
constructor(map?: Map<K, V>) {
|
|
739
|
-
if (map == null) return;
|
|
740
|
-
let keys = map.keys();
|
|
741
|
-
for (let key of keys) {
|
|
742
|
-
let value = map.get(key);
|
|
743
|
-
if (value != null) this.put(key, value);
|
|
744
|
-
}
|
|
745
|
-
}
|
|
746
|
-
/**添加一个键值对
|
|
747
|
-
* 返回自身
|
|
748
|
-
* @param {SEntry<K, V>} entry - 键值对
|
|
749
|
-
* @returns {SHashMap<K, V>} - 自身
|
|
750
|
-
*/
|
|
751
|
-
putEntry(entry: SEntry<K, V>): SHashMap<K, V> {
|
|
752
|
-
this._map.set(entry.getKey(), entry.getValue());
|
|
753
|
-
return this;
|
|
754
|
-
}
|
|
755
|
-
|
|
756
|
-
/**获取指定键的值
|
|
757
|
-
* @param {K} key - 键
|
|
758
|
-
* @returns {V | undefined} - 值
|
|
759
|
-
*/
|
|
760
|
-
get(key: K): V | undefined {
|
|
761
|
-
return this._map.get(key);
|
|
762
|
-
}
|
|
763
|
-
|
|
764
|
-
/**添加一个键值对
|
|
765
|
-
* 返回自身
|
|
766
|
-
* @param {K} key - 键
|
|
767
|
-
* @param {V} value - 值
|
|
768
|
-
* @returns {SHashMap<K, V>} - 自身
|
|
769
|
-
*/
|
|
770
|
-
put(key: K, value: V): SHashMap<K, V> {
|
|
771
|
-
this._map.set(key, value);
|
|
772
|
-
return this;
|
|
773
|
-
}
|
|
774
|
-
|
|
775
|
-
/**判断是否存在指定键
|
|
776
|
-
* @param {K} key - 键
|
|
777
|
-
* @returns {boolean} - 是否存在
|
|
778
|
-
*/
|
|
779
|
-
has(key: K): boolean {
|
|
780
|
-
return this._map.has(key);
|
|
781
|
-
}
|
|
782
|
-
|
|
783
|
-
/**获取所有键值对
|
|
784
|
-
* @returns {SList<SEntry<K, V>>} - 键值对列表
|
|
785
|
-
*/
|
|
786
|
-
entrys(): SList<SEntry<K, V>> {
|
|
787
|
-
let list = new SList<SEntry<K, V>>();
|
|
788
|
-
for (const [key, value] of this._map) list.push(new SEntry(key, value));
|
|
789
|
-
return list;
|
|
790
|
-
}
|
|
791
|
-
|
|
792
|
-
/**获取所有键
|
|
793
|
-
* @returns {SList<K>} - 键列表
|
|
794
|
-
*/
|
|
795
|
-
keys(): SList<K> {
|
|
796
|
-
let list = new SList<K>();
|
|
797
|
-
let it = this._map.keys();
|
|
798
|
-
for (let key of it) list.push(key);
|
|
799
|
-
return list;
|
|
800
|
-
}
|
|
801
|
-
|
|
802
|
-
/**获取所有值
|
|
803
|
-
* @returns {SList<V>} - 值列表
|
|
804
|
-
*/
|
|
805
|
-
values(): SList<V> {
|
|
806
|
-
let list = new SList<V>();
|
|
807
|
-
let it = this._map.values();
|
|
808
|
-
for (let val of it) list.push(val);
|
|
809
|
-
return list;
|
|
810
|
-
}
|
|
811
|
-
|
|
812
|
-
/**转换为entry数组,并获取迭代器
|
|
813
|
-
* @returns {SIterator<SEntry<K, V>>} - 迭代器
|
|
814
|
-
*/
|
|
815
|
-
iterator(): SIterator<SEntry<K, V>> {
|
|
816
|
-
return this.entrys().iterator();
|
|
817
|
-
}
|
|
818
|
-
|
|
819
|
-
/**删除指定键的键值对
|
|
820
|
-
* @param {K} key - 键
|
|
821
|
-
* @returns {V | undefined} - 被删除的值
|
|
822
|
-
*/
|
|
823
|
-
remove(key: K): V | undefined {
|
|
824
|
-
let out = this._map.get(key);
|
|
825
|
-
this._map.delete(key);
|
|
826
|
-
return out;
|
|
827
|
-
}
|
|
828
|
-
|
|
829
|
-
/**清空哈希表
|
|
830
|
-
* @returns {SHashMap<K, V>} - 自身
|
|
831
|
-
*/
|
|
832
|
-
clear(): SHashMap<K, V> {
|
|
833
|
-
this._map.clear();
|
|
834
|
-
return this;
|
|
835
|
-
}
|
|
836
|
-
|
|
837
|
-
/**判断哈希表是否为空
|
|
838
|
-
* @returns {boolean} - 是否为空
|
|
839
|
-
*/
|
|
840
|
-
isEmpty(): boolean {
|
|
841
|
-
return this.isEmpty();
|
|
842
|
-
}
|
|
843
|
-
|
|
844
|
-
/**判断是否存在指定值
|
|
845
|
-
* @param {V} val - 值
|
|
846
|
-
* @returns {boolean} - 是否存在
|
|
847
|
-
*/
|
|
848
|
-
containsValue(val: V): boolean {
|
|
849
|
-
return this.values().contains(val);
|
|
850
|
-
}
|
|
851
|
-
|
|
852
|
-
/**判断是否存在指定键
|
|
853
|
-
* @param {K} key - 键
|
|
854
|
-
* @returns {boolean} - 是否存在
|
|
855
|
-
*/
|
|
856
|
-
containsKey(key: K): boolean {
|
|
857
|
-
return this._map.has(key);
|
|
858
|
-
}
|
|
859
|
-
|
|
860
|
-
/**加载指定键的值,若不存在则添加默认值
|
|
861
|
-
* 返回键值
|
|
862
|
-
* @param {K} key - 键
|
|
863
|
-
* @param {V} def - 默认值
|
|
864
|
-
* @returns {V} - 值
|
|
865
|
-
*/
|
|
866
|
-
load(key: K, def: V): V {
|
|
867
|
-
if (this.containsKey(key)) return this.get(key)!;
|
|
868
|
-
this.put(key, def);
|
|
869
|
-
return def;
|
|
870
|
-
}
|
|
871
|
-
|
|
872
|
-
/**合并另一个哈希表,可选择是否覆盖已有键值对
|
|
873
|
-
* @param {SHashMap<K, V>} nmap - 另一个哈希表
|
|
874
|
-
* @param {boolean} [isCover=true] - 是否覆盖已有键值对,默认为 true
|
|
875
|
-
* @returns {SHashMap<K, V>} - 自身
|
|
876
|
-
*/
|
|
877
|
-
merge(nmap: SHashMap<K, V>, isCover: boolean = true): SHashMap<K, V> {
|
|
878
|
-
var it = nmap.iterator();
|
|
879
|
-
while (it.hasNext()) {
|
|
880
|
-
if (isCover) this.putEntry(it.next());
|
|
881
|
-
else {
|
|
882
|
-
var entry = it.next();
|
|
883
|
-
if (!this.containsKey(entry.getKey())) this.putEntry(entry);
|
|
884
|
-
}
|
|
885
|
-
}
|
|
886
|
-
return this;
|
|
887
|
-
}
|
|
888
|
-
|
|
889
|
-
/**获取哈希表大小(键的数量)
|
|
890
|
-
* @returns {number} - 大小
|
|
891
|
-
*/
|
|
892
|
-
size(): number {
|
|
893
|
-
return this._map.size;
|
|
894
|
-
}
|
|
895
|
-
/**对哈希表的每一个键值对进行加工,返回加工完成的键值对组成的新哈希表
|
|
896
|
-
* @param {MapCallback<SEntry<K, V>, SEntry<OK, OV>>} func - 加工函数
|
|
897
|
-
* @returns {SHashMap<OK, OV>} - 新哈希表
|
|
898
|
-
*/
|
|
899
|
-
map<OK, OV>(
|
|
900
|
-
func: MapCallback<SEntry<K, V>, SEntry<OK, OV>>
|
|
901
|
-
): SHashMap<OK, OV> {
|
|
902
|
-
let nmap = new SHashMap<OK, OV>();
|
|
903
|
-
this.entrys()
|
|
904
|
-
.map(func)
|
|
905
|
-
.each((val) => nmap.putEntry(val));
|
|
906
|
-
return nmap;
|
|
907
|
-
}
|
|
908
|
-
|
|
909
|
-
/**返回符合条件的键值对组成的新哈希表
|
|
910
|
-
* @param {FiltCallback<SEntry<K, V>>): boolean} func - 条件函数
|
|
911
|
-
* @returns {SHashMap<K, V>} - 新哈希表
|
|
912
|
-
*/
|
|
913
|
-
filt(func: FiltCallback<SEntry<K, V>>): SHashMap<K, V> {
|
|
914
|
-
let nmap = new SHashMap<K, V>();
|
|
915
|
-
this.entrys()
|
|
916
|
-
.filt(func)
|
|
917
|
-
.each((val) => nmap.putEntry(val));
|
|
918
|
-
return nmap;
|
|
919
|
-
}
|
|
920
|
-
|
|
921
|
-
/**遍历哈希表的每一个键值对
|
|
922
|
-
* @param {EachCallback<SEntry<K, V>>} func - 遍历函数
|
|
923
|
-
* @returns {SHashMap<K, V>} - 自身
|
|
924
|
-
*/
|
|
925
|
-
each(func: EachCallback<SEntry<K, V>>): SHashMap<K, V> {
|
|
926
|
-
this.entrys().each(func);
|
|
927
|
-
return this;
|
|
928
|
-
}
|
|
929
|
-
|
|
930
|
-
/**对哈希表进行统计
|
|
931
|
-
* @param {O} init - 初始值
|
|
932
|
-
* @param {AggrCallback<SEntry<K, V>,O>} func - 统计函数
|
|
933
|
-
* @returns {O} - 统计结果
|
|
934
|
-
*/
|
|
935
|
-
aggr<O>(init: O, func: AggrCallback<SEntry<K, V>, O>): O {
|
|
936
|
-
return this.entrys().aggr(init, func);
|
|
937
|
-
}
|
|
938
|
-
|
|
939
|
-
/**对哈希表进行缩减
|
|
940
|
-
* @param {AggrCallback<SEntry<K, V>,V>} func - 缩减函数
|
|
941
|
-
* @param {V} init - 初始值
|
|
942
|
-
* @returns {V} - 缩减结果
|
|
943
|
-
*/
|
|
944
|
-
reduce(func: AggrCallback<SEntry<K, V>, V>, init?: V): V | null {
|
|
945
|
-
if (this.isEmpty()) {
|
|
946
|
-
if (init === undefined) return null;
|
|
947
|
-
return init;
|
|
948
|
-
}
|
|
949
|
-
|
|
950
|
-
let entries = this.entrys();
|
|
951
|
-
let result: V;
|
|
952
|
-
if (init === undefined) {
|
|
953
|
-
result = entries.get(0).getValue();
|
|
954
|
-
entries.shift();
|
|
955
|
-
} else result = init;
|
|
956
|
-
|
|
957
|
-
entries.each((val, index, list) => {
|
|
958
|
-
result = func(result, val, index, list);
|
|
959
|
-
});
|
|
960
|
-
return result;
|
|
961
|
-
}
|
|
962
|
-
|
|
963
|
-
//重载TypeScript操作符
|
|
964
|
-
[Symbol.iterator]() {
|
|
965
|
-
let it = this.iterator();
|
|
966
|
-
|
|
967
|
-
return {
|
|
968
|
-
next(): { value: SEntry<K, V> | null; done: boolean } {
|
|
969
|
-
if (it.hasNext()) {
|
|
970
|
-
return { value: it.next(), done: false };
|
|
971
|
-
} else {
|
|
972
|
-
return { value: null, done: true };
|
|
973
|
-
}
|
|
974
|
-
},
|
|
975
|
-
};
|
|
976
|
-
}
|
|
977
|
-
}
|
|
978
|
-
|
|
979
|
-
class SKVC {
|
|
980
|
-
private stringMap: SHashMap<string, string> = new SHashMap();
|
|
981
|
-
|
|
982
|
-
constructor() {}
|
|
983
|
-
}
|
|
984
|
-
|
|
985
|
-
/**函数组合器 */
|
|
986
|
-
export class Composer<Result,PreArg = Result> {
|
|
987
|
-
/**组合函数列表 */
|
|
988
|
-
private funcs: Function[] = [];
|
|
989
|
-
private constructor(){};
|
|
990
|
-
/**添加单个参数与返回值不同的函数 */
|
|
991
|
-
public static push<Result,Arg>(func: (arg: Arg) => Result): Composer<Result,Arg>;
|
|
992
|
-
/**添加多个参数与返回值相同的函数 */
|
|
993
|
-
public static push<Result>(func:((arg: Result) => Result), ...funcs: ((arg: Result) => Result)[]): Composer<Result>;
|
|
994
|
-
public static push(...funcs: Function[]){
|
|
995
|
-
const newComposer = new Composer<any>();
|
|
996
|
-
newComposer.funcs = [...funcs];
|
|
997
|
-
return newComposer;
|
|
998
|
-
}
|
|
999
|
-
|
|
1000
|
-
/**添加单个参数与返回值不同的函数 */
|
|
1001
|
-
public push<T>(func: (arg: T) => PreArg): Composer<Result,T>;
|
|
1002
|
-
/**添加多个参数与返回值相同的函数 */
|
|
1003
|
-
public push(func:((arg: Result) => Result), ...funcs: ((arg: PreArg) => PreArg)[]): Composer<Result,PreArg>;
|
|
1004
|
-
public push(...funcs: Function[]): Composer<Result,any> {
|
|
1005
|
-
const newComposer = new Composer<Result>();
|
|
1006
|
-
newComposer.funcs = [...this.funcs, ...funcs];
|
|
1007
|
-
return newComposer;
|
|
1008
|
-
}
|
|
1009
|
-
/**组合函数 */
|
|
1010
|
-
public compose():(arg:PreArg)=>Result {
|
|
1011
|
-
return (arg:PreArg) => this.funcs.reduceRight((value, func) => func(value), arg) as any as Result;
|
|
1012
|
-
}
|
|
1013
|
-
/**直接调用 */
|
|
1014
|
-
public invoke(arg:PreArg):Result {
|
|
1015
|
-
return this.funcs.reduceRight((value, func) => func(value), arg) as any as Result;
|
|
1016
|
-
}
|
|
1017
|
-
}
|
|
1018
|
-
/**函数管道器 */
|
|
1019
|
-
export class Piper<Arg, Result = Arg> {
|
|
1020
|
-
/**管道函数列表 */
|
|
1021
|
-
private funcs: Function[] = [];
|
|
1022
|
-
private constructor(){};
|
|
1023
|
-
/**添加单个参数与返回值不同的函数 */
|
|
1024
|
-
public static pipe<Arg, Result>(func: (arg: Arg) => Result): Piper<Arg, Result>;
|
|
1025
|
-
/**添加多个参数与返回值相同的函数 */
|
|
1026
|
-
public static pipe<Arg>(func:((arg: Arg) => Arg), ...funcs: ((arg: Arg) => Arg)[]): Piper<Arg>;
|
|
1027
|
-
public static pipe(...funcs: Function[]){
|
|
1028
|
-
const newPiper = new Piper<any>();
|
|
1029
|
-
newPiper.funcs = [...funcs];
|
|
1030
|
-
return newPiper;
|
|
1031
|
-
}
|
|
1032
|
-
|
|
1033
|
-
/**添加单个参数与返回值不同的函数 */
|
|
1034
|
-
public pipe<T>(func: (arg: Result) => T): Piper<Arg, T>;
|
|
1035
|
-
/**添加多个参数与返回值相同的函数 */
|
|
1036
|
-
public pipe(func:((arg: Result) => Result), ...funcs: ((arg: Result) => Result)[]): Piper<Arg, Result>;
|
|
1037
|
-
public pipe(...funcs: Function[]): Piper<Arg, any> {
|
|
1038
|
-
const newPiper = new Piper<Arg>();
|
|
1039
|
-
newPiper.funcs = [...this.funcs, ...funcs];
|
|
1040
|
-
return newPiper;
|
|
1041
|
-
}
|
|
1042
|
-
/**管道函数 */
|
|
1043
|
-
public pipeline():(arg:Arg)=>Result {
|
|
1044
|
-
return (arg:Arg) => this.funcs.reduce((value, func) => func(value), arg) as any as Result;
|
|
1045
|
-
}
|
|
1046
|
-
/**直接调用 */
|
|
1047
|
-
public invoke(arg:Arg):Result {
|
|
1048
|
-
return this.funcs.reduce((value, func) => func(value), arg) as any as Result;
|
|
1049
|
-
}
|
|
1050
|
-
}
|
|
1051
|
-
|
|
1
|
+
type struct = number | string;
|
|
2
|
+
|
|
3
|
+
/**遍历函数
|
|
4
|
+
*/
|
|
5
|
+
interface EachCallback<T> {
|
|
6
|
+
/**
|
|
7
|
+
* @param {T} value - 值
|
|
8
|
+
* @param {number} index - 下标
|
|
9
|
+
* @param {SList<T>} list - 数组
|
|
10
|
+
* @returns {void}
|
|
11
|
+
*/
|
|
12
|
+
(value: T, index: number, list: SList<T>): void;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**加工函数
|
|
16
|
+
*/
|
|
17
|
+
interface MapCallback<T, U> {
|
|
18
|
+
/**
|
|
19
|
+
* @param {T} value - 值
|
|
20
|
+
* @param {number} index - 下标
|
|
21
|
+
* @param {SList<T>} list - 数组
|
|
22
|
+
* @returns {U} - 返回值
|
|
23
|
+
*/
|
|
24
|
+
(value: T, index: number, list: SList<T>): U;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**过滤函数
|
|
28
|
+
*/
|
|
29
|
+
interface FiltCallback<T> {
|
|
30
|
+
/**
|
|
31
|
+
* @param {T} value - 值
|
|
32
|
+
* @param {number} index - 下标
|
|
33
|
+
* @param {SList<T>} list - 数组
|
|
34
|
+
* @returns {boolean} - 返回值
|
|
35
|
+
*/
|
|
36
|
+
(value: T, index: number, list: SList<T>): boolean;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**统计函数
|
|
40
|
+
*/
|
|
41
|
+
interface AggrCallback<T, U> {
|
|
42
|
+
/**
|
|
43
|
+
* @param {U} accumulator - 累加器
|
|
44
|
+
* @param {T} value - 值
|
|
45
|
+
* @param {number} index - 下标
|
|
46
|
+
* @param {SList<T>} list - 数组
|
|
47
|
+
* @returns {U} - 返回值
|
|
48
|
+
*/
|
|
49
|
+
(accumulator: U, value: T, index: number, list: SList<T>): U;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**缩减函数
|
|
53
|
+
*/
|
|
54
|
+
interface ReduceCallback<T> {
|
|
55
|
+
/**
|
|
56
|
+
* @param {T} previousValue - 上一个值/累加值
|
|
57
|
+
* @param {T} currentValue - 当前值
|
|
58
|
+
* @param {number} currentIndex - 当前下标
|
|
59
|
+
* @param {SList<T>} list - 数组
|
|
60
|
+
* @returns {T} - 返回值
|
|
61
|
+
*/
|
|
62
|
+
(
|
|
63
|
+
previousValue: T,
|
|
64
|
+
currentValue: T,
|
|
65
|
+
currentIndex: number,
|
|
66
|
+
list: SList<T>
|
|
67
|
+
): T;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**排序函数
|
|
71
|
+
*/
|
|
72
|
+
interface SortCallback<T> {
|
|
73
|
+
/**
|
|
74
|
+
* @param {T} a - 值a
|
|
75
|
+
* @param {T} b - 值b
|
|
76
|
+
* @returns {number} - 返回值
|
|
77
|
+
*/
|
|
78
|
+
(a: T, b: T): number;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export class SList<T> {
|
|
82
|
+
private _arr: Array<T>;
|
|
83
|
+
/**建立0长度的SList */
|
|
84
|
+
constructor();
|
|
85
|
+
/**建立一个长度为 obj 的SList */
|
|
86
|
+
constructor(obj:number);
|
|
87
|
+
/**根据obj建立SList */
|
|
88
|
+
constructor(obj:Array<T>);
|
|
89
|
+
constructor(obj?: Array<T> | number) {
|
|
90
|
+
if (typeof obj == "number") this._arr = new Array<T>(obj);
|
|
91
|
+
else if (Array.isArray(obj)) this._arr = obj;
|
|
92
|
+
else this._arr = [];
|
|
93
|
+
}
|
|
94
|
+
/**返回数组长度
|
|
95
|
+
* @returns {number} - 长度
|
|
96
|
+
*/
|
|
97
|
+
size(): number {
|
|
98
|
+
return this._arr.length;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**获取指定下标的元素
|
|
102
|
+
* @param {number} index - 下标
|
|
103
|
+
* @returns {T} - 目标元素
|
|
104
|
+
*/
|
|
105
|
+
get(index: number): T {
|
|
106
|
+
return this._arr[index];
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**设置指定下标的元素
|
|
110
|
+
* 返回自身 改变自身
|
|
111
|
+
* @param {number} index - 下标
|
|
112
|
+
* @param {T} value - 值
|
|
113
|
+
* @returns {SList<T>} - 自身
|
|
114
|
+
*/
|
|
115
|
+
set(index: number, value: T): SList<T> {
|
|
116
|
+
this._arr[index] = value;
|
|
117
|
+
return this;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**连接两个数组
|
|
121
|
+
* @param {SList<T>} list - 目标数组
|
|
122
|
+
* @returns {SList<T>} - 新数组
|
|
123
|
+
*/
|
|
124
|
+
concat(list: SList<T>): SList<T> {
|
|
125
|
+
return new SList<T>(this._arr.concat(list._arr));
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/**在数组末尾添加一个元素
|
|
129
|
+
* 返回自身 改变自身
|
|
130
|
+
* @param {T} value - 值
|
|
131
|
+
* @returns {SList<T>} - 自身
|
|
132
|
+
*/
|
|
133
|
+
push(value: T): SList<T> {
|
|
134
|
+
this._arr.push(value);
|
|
135
|
+
return this;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/**在数组末尾添加一个数组
|
|
139
|
+
* 改变自身
|
|
140
|
+
* @param {SList<T>} list - 目标数组
|
|
141
|
+
* @returns {SList<T>} - 自身
|
|
142
|
+
*/
|
|
143
|
+
pushList(list: SList<T>) {
|
|
144
|
+
this._arr = this._arr.concat(list._arr);
|
|
145
|
+
return this;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/**截取从起始点到结束点之前的一段数组
|
|
149
|
+
* @param {number} strat - 起始点
|
|
150
|
+
* @param {number} end - 结束点
|
|
151
|
+
* @returns {SList<T>} - 新数组
|
|
152
|
+
*/
|
|
153
|
+
slice(strat: number, end: number): SList<T> {
|
|
154
|
+
return new SList(this._arr.slice(strat, end));
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/**翻转数组
|
|
158
|
+
* 改变自身
|
|
159
|
+
* @returns {SList<T>} - 自身
|
|
160
|
+
*/
|
|
161
|
+
reverse(): SList<T> {
|
|
162
|
+
this._arr.reverse();
|
|
163
|
+
return this;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/**将SList转换为数组
|
|
167
|
+
* @returns {Array<T>} - 数组
|
|
168
|
+
*/
|
|
169
|
+
toArray(): Array<T> {
|
|
170
|
+
return ([] as T[]).concat(this._arr);
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
/**将SList转换为SStream
|
|
174
|
+
* @param {number} concurrent - 并发数
|
|
175
|
+
* @returns {SStream<T>} - 流
|
|
176
|
+
*/
|
|
177
|
+
toSStream(concurrent?: number): SStream<T> {
|
|
178
|
+
return new SStream<T>(this._arr, concurrent);
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
/**返回指定元素在数组中首次出现的位置
|
|
182
|
+
* @param {T} value - 目标元素
|
|
183
|
+
* @returns {number} - 下标
|
|
184
|
+
*/
|
|
185
|
+
indexOf(value: T): number {
|
|
186
|
+
return this._arr.indexOf(value);
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
/**返回指定元素在数组中最后一次出现的位置
|
|
190
|
+
* @param {T} value - 目标元素
|
|
191
|
+
* @returns {number} - 下标
|
|
192
|
+
*/
|
|
193
|
+
lastIndexOf(value: T): number {
|
|
194
|
+
return this._arr.lastIndexOf(value);
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
/**判断数组中是否包含指定元素
|
|
198
|
+
* @param {T} value - 目标元素
|
|
199
|
+
* @returns {boolean} - 是否包含
|
|
200
|
+
*/
|
|
201
|
+
contains(value: T): boolean {
|
|
202
|
+
return this._arr.includes(value);
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
/**获取迭代器
|
|
206
|
+
* @returns {SIterator<T>} - 迭代器
|
|
207
|
+
*/
|
|
208
|
+
iterator(): SIterator<T> {
|
|
209
|
+
return new SIterator<T>(this);
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
/**平分数组
|
|
213
|
+
* @param {number} count - 份数
|
|
214
|
+
* @param {"average" | "chunk"} mode - 模式 average:轮询平均分 chunk:切块均分
|
|
215
|
+
* @returns {SList<SList<T>>} - 新数组
|
|
216
|
+
*/
|
|
217
|
+
divide(
|
|
218
|
+
count: number,
|
|
219
|
+
mode: "average" | "chunk" = "average"
|
|
220
|
+
): SList<SList<T>> {
|
|
221
|
+
if (count <= 0) return new SList<SList<T>>();
|
|
222
|
+
if (count == 1) return new SList<SList<T>>([this.clone()]);
|
|
223
|
+
|
|
224
|
+
let result = new SList<SList<T>>();
|
|
225
|
+
switch (mode) {
|
|
226
|
+
//轮询平均分
|
|
227
|
+
default:
|
|
228
|
+
case "average":
|
|
229
|
+
for (let i = 0; i < count; i++) {
|
|
230
|
+
let clist = new SList<T>();
|
|
231
|
+
let size = this.size();
|
|
232
|
+
for (let j = i; j < size; j += count)
|
|
233
|
+
clist.push(this.get(j));
|
|
234
|
+
result.push(clist);
|
|
235
|
+
}
|
|
236
|
+
break;
|
|
237
|
+
//切块均分
|
|
238
|
+
case "chunk":
|
|
239
|
+
let chunkSize = Math.ceil(this.size() / count);
|
|
240
|
+
for (let i = 0; i < count; i++) {
|
|
241
|
+
let start = i * chunkSize;
|
|
242
|
+
let end = (i + 1) * chunkSize;
|
|
243
|
+
if (end > this.size()) end = this.size();
|
|
244
|
+
result.push(this.slice(start, end));
|
|
245
|
+
}
|
|
246
|
+
break;
|
|
247
|
+
}
|
|
248
|
+
return result;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
/**从index开始删除count个元素,返回删除的元素数组
|
|
252
|
+
* 改变自身
|
|
253
|
+
* @param {number} index - 起始点
|
|
254
|
+
* @param {number} count - 数量
|
|
255
|
+
* @returns {SList<T>} - 删除的元素数组
|
|
256
|
+
*/
|
|
257
|
+
removeRange(index: number, count: number): SList<T> {
|
|
258
|
+
let narr = this._arr.splice(index, count);
|
|
259
|
+
return new SList<T>(narr);
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
/**删除对应下标下的元素,返回删除的元素
|
|
263
|
+
* 改变自身
|
|
264
|
+
* @param {number} i - 下标
|
|
265
|
+
* @returns {T|null} - 删除的元素
|
|
266
|
+
*/
|
|
267
|
+
remove(i: number): T|null {
|
|
268
|
+
if (i >= 0 && i < this.size())
|
|
269
|
+
return this._arr.splice(i, 1)[0];
|
|
270
|
+
return null;
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
/**删除第一个匹配的项目,返回自身
|
|
274
|
+
* 改变自身
|
|
275
|
+
* @param {T} obj - 需删除目标
|
|
276
|
+
* @returns {SList<T>} - 自身
|
|
277
|
+
*/
|
|
278
|
+
removeMember(obj: T): SList<T> {
|
|
279
|
+
let index = this.indexOf(obj);
|
|
280
|
+
if (index > -1) this.remove(index);
|
|
281
|
+
return this;
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
/**删除所有匹配的项目
|
|
285
|
+
* 改变自身
|
|
286
|
+
* @param {T} obj - 需删除目标
|
|
287
|
+
* @returns {SList<T>} - 自身
|
|
288
|
+
*/
|
|
289
|
+
removeAllMember(obj: T): SList<T> {
|
|
290
|
+
while (this.contains(obj)) this.removeMember(obj);
|
|
291
|
+
return this;
|
|
292
|
+
}
|
|
293
|
+
/**在这个下标对应的元素前添加一个元素
|
|
294
|
+
* 改变自身
|
|
295
|
+
* @param {number} index - 下标
|
|
296
|
+
* @param {T} obj - 添加对象
|
|
297
|
+
* @returns {SList<T>} - 自身
|
|
298
|
+
*/
|
|
299
|
+
insert(index: number, obj: T): SList<T> {
|
|
300
|
+
this._arr.splice(index, 0, obj);
|
|
301
|
+
return this;
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
/**在这个下标对应的元素前添加一组元素
|
|
305
|
+
* 改变自身
|
|
306
|
+
* @param {number} index - 下标
|
|
307
|
+
* @param {SList<T>} obj - 添加对象
|
|
308
|
+
* @returns {SList<T>} - 自身
|
|
309
|
+
*/
|
|
310
|
+
insertRange(index: number, obj: SList<T>): SList<T> {
|
|
311
|
+
this._arr.splice(index, 0, ...obj._arr);
|
|
312
|
+
return this;
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
/**删除并返回最后一个元素
|
|
316
|
+
* 改变自身
|
|
317
|
+
* @returns {T | null} - 最后一个元素
|
|
318
|
+
*/
|
|
319
|
+
pop(): T | null {
|
|
320
|
+
let val = this._arr.pop();
|
|
321
|
+
return val == undefined ? null : val;
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
/**删除并返回第一个元素
|
|
325
|
+
* 改变自身
|
|
326
|
+
* @returns {T | null} - 第一个元素
|
|
327
|
+
*/
|
|
328
|
+
shift(): T | null {
|
|
329
|
+
let val = this._arr.shift();
|
|
330
|
+
return val == undefined ? null : val;
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
|
|
334
|
+
|
|
335
|
+
/**克隆数组
|
|
336
|
+
* @returns {SList<T>} - 新数组
|
|
337
|
+
*/
|
|
338
|
+
clone(): SList<T> {
|
|
339
|
+
return new SList(([] as T[]).concat(this._arr));
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
/**判断数组是否为空
|
|
343
|
+
* @returns {boolean} - 是否为空
|
|
344
|
+
*/
|
|
345
|
+
isEmpty(): boolean {
|
|
346
|
+
return this.size() == 0;
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
/**删除数组中的重复元素
|
|
350
|
+
* 改变自身
|
|
351
|
+
* @returns {SList<T>} - 自身
|
|
352
|
+
*/
|
|
353
|
+
removeDuplicates(): SList<T> {
|
|
354
|
+
this._arr = Array.from(new Set(this._arr));
|
|
355
|
+
return this;
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
/**交集
|
|
359
|
+
* @param {SList<T>[]} lists - 数组列表
|
|
360
|
+
* @returns {SList<T>} - 新数组
|
|
361
|
+
*/
|
|
362
|
+
intersection(...lists: SList<T>[]): SList<T> {
|
|
363
|
+
let nlist = this.clone().removeDuplicates();
|
|
364
|
+
|
|
365
|
+
for (let list of lists) nlist = list.filt((val) => nlist.contains(val));
|
|
366
|
+
|
|
367
|
+
return nlist;
|
|
368
|
+
}
|
|
369
|
+
/**并集
|
|
370
|
+
* @param {SList<T>[]} lists - 数组列表
|
|
371
|
+
* @returns {SList<T>} - 新数组
|
|
372
|
+
*/
|
|
373
|
+
union(...lists: SList<T>[]): SList<T> {
|
|
374
|
+
let nlist = this.clone().removeDuplicates();
|
|
375
|
+
|
|
376
|
+
for (let list of lists) {
|
|
377
|
+
list.each((val) => {
|
|
378
|
+
if (!nlist.contains(val)) nlist.push(val);
|
|
379
|
+
});
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
return nlist;
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
/**返回符合条件的成员组成的新数组
|
|
386
|
+
* @param {FiltCallback<T>} func - 条件函数
|
|
387
|
+
* @returns {SList<T>} - 新数组
|
|
388
|
+
*/
|
|
389
|
+
filt(func: FiltCallback<T>): SList<T> {
|
|
390
|
+
let nlist = new SList<T>(this.size());
|
|
391
|
+
let length = 0;
|
|
392
|
+
let it = this.iterator();
|
|
393
|
+
while (it.hasNext()) {
|
|
394
|
+
let tmpObj = it.next();
|
|
395
|
+
if (func(tmpObj, it.currIndex(), this)) {
|
|
396
|
+
nlist.set(length, tmpObj);
|
|
397
|
+
length++;
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
return nlist.slice(0, length);
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
/**遍历数组的每一个元素
|
|
404
|
+
* @param {EachCallback<T>} func - 遍历函数 (value: T, index: number, list: SList<T>): void
|
|
405
|
+
* @returns {SList<T>} - 自身
|
|
406
|
+
*/
|
|
407
|
+
each(func: EachCallback<T>): SList<T> {
|
|
408
|
+
let it = this.iterator();
|
|
409
|
+
while (it.hasNext()) func(it.next(), it.currIndex(), this);
|
|
410
|
+
return this;
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
/**对数组的每一个元素进行加工,返回加工完成的成员组成的新数组
|
|
414
|
+
* @param {MapCallback<T,O>} func - 加工函数 (value: T, index: number, list: SList<T>): O
|
|
415
|
+
* @returns {SList<O>} - 新数组
|
|
416
|
+
*/
|
|
417
|
+
map<O>(func: MapCallback<T, O>): SList<O> {
|
|
418
|
+
let nlist = new SList<O>(this.size());
|
|
419
|
+
let it = this.iterator();
|
|
420
|
+
while (it.hasNext())
|
|
421
|
+
nlist.set(it.nextIndex(), func(it.next(), it.currIndex(), this));
|
|
422
|
+
return nlist;
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
/**对数组进行排序
|
|
426
|
+
* 如函数返回值大于 0 则将 x 排在 y 后面,小于 0 则将 x 排在 y 前面
|
|
427
|
+
* 改变自身
|
|
428
|
+
* @param {SortCallback<T>} func - 排序函数 (a: T, b: T): number
|
|
429
|
+
* @returns {SList<T>} - 自身
|
|
430
|
+
*/
|
|
431
|
+
sort(func: SortCallback<T>): SList<T> {
|
|
432
|
+
this._arr.sort(func);
|
|
433
|
+
return this;
|
|
434
|
+
}
|
|
435
|
+
/**对数组进行统计 aggregate
|
|
436
|
+
* 遍历数组,并将每次遍历的结果与下一次遍历的元素一起传入函数,最后返回最后一次遍历的结果
|
|
437
|
+
* @param {O} init - 初始值
|
|
438
|
+
* @param {AggrCallback<T,O>} func - 统计函数 (value: T, accumulator: U, index: number, list: SList<T>): U
|
|
439
|
+
* @returns {O} - 统计结果
|
|
440
|
+
*/
|
|
441
|
+
public aggr<O>(init: O, func: AggrCallback<T, O>): O {
|
|
442
|
+
let it = this.iterator();
|
|
443
|
+
let tmpObj = init;
|
|
444
|
+
while (it.hasNext())
|
|
445
|
+
tmpObj = func(tmpObj, it.next(), it.currIndex(), this);
|
|
446
|
+
return tmpObj;
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
/**对数组进行缩减
|
|
450
|
+
* 遍历数组,并将每次遍历的结果与下一次遍历的元素一起传入函数,最后返回最后一次遍历的结果
|
|
451
|
+
* @param {ReduceCallback<T>} func - 缩减函数 (previousValue: T, currentValue: T, currentIndex: number, array: SList<T>):T
|
|
452
|
+
* @param {T} init - 初始值
|
|
453
|
+
* @returns {T} - 缩减结果
|
|
454
|
+
*/
|
|
455
|
+
public reduce(func: ReduceCallback<T>, init?: T): T | null {
|
|
456
|
+
if (this.size() === 0) return null;
|
|
457
|
+
let it = this.iterator();
|
|
458
|
+
let tmpObj = init === undefined ? it.next() : init;
|
|
459
|
+
while (it.hasNext())
|
|
460
|
+
tmpObj = func(tmpObj, it.next(), it.currIndex(), this);
|
|
461
|
+
return tmpObj;
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
//重载TypeScript操作符
|
|
465
|
+
[Symbol.iterator]() {
|
|
466
|
+
let it = this.iterator();
|
|
467
|
+
|
|
468
|
+
return {
|
|
469
|
+
next(): { value: T | null; done: boolean } {
|
|
470
|
+
if (it.hasNext()) {
|
|
471
|
+
return { value: it.next(), done: false };
|
|
472
|
+
} else {
|
|
473
|
+
return { value: null, done: true };
|
|
474
|
+
}
|
|
475
|
+
},
|
|
476
|
+
};
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
interface SStreamOperation<T, U> {
|
|
481
|
+
(item: T): Promise<U>;
|
|
482
|
+
}
|
|
483
|
+
export class SStream<T> {
|
|
484
|
+
/**并发数*/
|
|
485
|
+
private _concurrent: number;
|
|
486
|
+
/**原始列表*/
|
|
487
|
+
private _slist: SList<T>;
|
|
488
|
+
/**加工函数列表*/
|
|
489
|
+
private _operation: Array<SStreamOperation<T, T>> = [];
|
|
490
|
+
constructor(slist: SList<T> | Array<T>, concurrent: number = 1) {
|
|
491
|
+
if (slist instanceof SList) this._slist = slist;
|
|
492
|
+
else if (Array.isArray(slist)) this._slist = new SList(slist);
|
|
493
|
+
else this._slist = new SList();
|
|
494
|
+
this._concurrent = concurrent;
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
/**映射加工
|
|
498
|
+
* @param {SStreamOperation<T,U>} operation - 加工函数
|
|
499
|
+
* @returns {SStream<U>} - 新流
|
|
500
|
+
*/
|
|
501
|
+
map<U>(operation: SStreamOperation<T, U>): SStream<U> {
|
|
502
|
+
this._operation.push(operation as any);
|
|
503
|
+
return this as any as SStream<U>;
|
|
504
|
+
}
|
|
505
|
+
/**遍历
|
|
506
|
+
* 返回自身
|
|
507
|
+
* @param {SStreamOperation<T,void>} operation - 遍历函数
|
|
508
|
+
* @returns {SStream<T>} - 自身
|
|
509
|
+
*/
|
|
510
|
+
each(operation: SStreamOperation<T, void>): SStream<T> {
|
|
511
|
+
let opera = async (item: T) => {
|
|
512
|
+
operation(item);
|
|
513
|
+
return item;
|
|
514
|
+
};
|
|
515
|
+
this._operation.push(opera);
|
|
516
|
+
return this;
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
//终结操作
|
|
520
|
+
/**应用加工
|
|
521
|
+
* @returns {SStream<T>} - 自身
|
|
522
|
+
*/
|
|
523
|
+
async appendOperations(): Promise<SStream<T>> {
|
|
524
|
+
if (this._operation.length == 0) return this;
|
|
525
|
+
|
|
526
|
+
let nlist = new SList<SList<T>>();
|
|
527
|
+
let promiseList: Array<Promise<any>> = [];
|
|
528
|
+
//均分处理
|
|
529
|
+
let sliceList = this._slist.divide(this._concurrent);
|
|
530
|
+
for (let i = 0; i < this._concurrent; i++) {
|
|
531
|
+
let subList = sliceList.get(i);
|
|
532
|
+
if (!subList) continue;
|
|
533
|
+
promiseList.push(
|
|
534
|
+
new Promise(async () => {
|
|
535
|
+
let result = new SList<T>();
|
|
536
|
+
for (let item of subList) {
|
|
537
|
+
if (!item) continue;
|
|
538
|
+
for (let operation of this._operation)
|
|
539
|
+
item = await operation(item);
|
|
540
|
+
result.push(item);
|
|
541
|
+
}
|
|
542
|
+
nlist.set(i, result);
|
|
543
|
+
})
|
|
544
|
+
);
|
|
545
|
+
}
|
|
546
|
+
await Promise.all(promiseList);
|
|
547
|
+
//拼接结果 轮询均分
|
|
548
|
+
let result = new SList<T>(this._slist.size());
|
|
549
|
+
for (let i = 0; i < this._concurrent; i++) {
|
|
550
|
+
let subList = nlist.get(i);
|
|
551
|
+
if (!subList) continue;
|
|
552
|
+
let subSize = subList.size();
|
|
553
|
+
for (let j = 0; j < subSize; j++)
|
|
554
|
+
result.set(i + j * this._concurrent, subList.get(j));
|
|
555
|
+
}
|
|
556
|
+
this._slist = result;
|
|
557
|
+
this._operation = [];
|
|
558
|
+
return this;
|
|
559
|
+
}
|
|
560
|
+
/**转换为SList
|
|
561
|
+
* @returns {SList<T>} - 数组
|
|
562
|
+
*/
|
|
563
|
+
async toSList(): Promise<SList<T>> {
|
|
564
|
+
await this.appendOperations();
|
|
565
|
+
return this._slist;
|
|
566
|
+
}
|
|
567
|
+
/**转换为数组
|
|
568
|
+
* @returns {Array<T>} - 数组
|
|
569
|
+
*/
|
|
570
|
+
async toArray(): Promise<Array<T>> {
|
|
571
|
+
await this.appendOperations();
|
|
572
|
+
return this._slist.toArray();
|
|
573
|
+
}
|
|
574
|
+
}
|
|
575
|
+
|
|
576
|
+
export class SIterator<T> {
|
|
577
|
+
private _index = -1;
|
|
578
|
+
private _list: SList<T>;
|
|
579
|
+
constructor(list: SList<T>) {
|
|
580
|
+
this._list = list;
|
|
581
|
+
}
|
|
582
|
+
/**判断还有没有下一个元素
|
|
583
|
+
* @returns {boolean} - 是否有下一个元素
|
|
584
|
+
*/
|
|
585
|
+
hasNext(): boolean {
|
|
586
|
+
return this._index < this.size() - 1 && this._index >= -1;
|
|
587
|
+
}
|
|
588
|
+
|
|
589
|
+
/**判断当前下标有无元素
|
|
590
|
+
* @returns {boolean} - 是否有当前元素
|
|
591
|
+
*/
|
|
592
|
+
hasCurr(): boolean {
|
|
593
|
+
return this._index < this.size() && this._index >= 0;
|
|
594
|
+
}
|
|
595
|
+
|
|
596
|
+
/**判断还有没有上一个元素
|
|
597
|
+
* @returns {boolean} - 是否有上一个元素
|
|
598
|
+
*/
|
|
599
|
+
hasPre(): boolean {
|
|
600
|
+
return this._index < this.size() + 1 && this._index >= 1;
|
|
601
|
+
}
|
|
602
|
+
|
|
603
|
+
/**返回下一个下标指向的数组内成员,然后下标自加1
|
|
604
|
+
* @returns {T} - 下一个成员
|
|
605
|
+
*/
|
|
606
|
+
next(): T {
|
|
607
|
+
if (this.hasNext()) return this._list.get(++this._index);
|
|
608
|
+
else
|
|
609
|
+
throw "一个 SIterator 迭代器的 next 函数出错,可能是在下标到底时还在尝试迭代";
|
|
610
|
+
}
|
|
611
|
+
|
|
612
|
+
/**返回上一个下标指向的数组内成员,然后下标自减1
|
|
613
|
+
* @returns {T} - 上一个成员
|
|
614
|
+
*/
|
|
615
|
+
pre(): T {
|
|
616
|
+
if (this.hasPre()) return this._list.get(--this._index);
|
|
617
|
+
else
|
|
618
|
+
throw "一个 SIterator 迭代器的 pre 函数出错,可能是在下标小于1时还在尝试迭代";
|
|
619
|
+
}
|
|
620
|
+
|
|
621
|
+
/**返回当前下标指向的数组内成员
|
|
622
|
+
* @returns {T} - 当前成员
|
|
623
|
+
*/
|
|
624
|
+
curr(): T {
|
|
625
|
+
if (this.hasCurr()) return this._list.get(this._index);
|
|
626
|
+
else
|
|
627
|
+
throw "一个 SIterator 迭代器的 curr 函数出错,可能是当前下标不包含元素/当前下标已越界";
|
|
628
|
+
}
|
|
629
|
+
|
|
630
|
+
/**返回遍历长度
|
|
631
|
+
* @returns {number} - 遍历长度
|
|
632
|
+
*/
|
|
633
|
+
size(): number {
|
|
634
|
+
return this._list.size();
|
|
635
|
+
}
|
|
636
|
+
|
|
637
|
+
/**获取下个下标
|
|
638
|
+
* @returns {number} - 下个下标
|
|
639
|
+
*/
|
|
640
|
+
nextIndex(): number {
|
|
641
|
+
return this._index + 1;
|
|
642
|
+
}
|
|
643
|
+
|
|
644
|
+
/**获取当前下标
|
|
645
|
+
* @return {number} - 当前下标
|
|
646
|
+
*/
|
|
647
|
+
currIndex(): number {
|
|
648
|
+
return this._index;
|
|
649
|
+
}
|
|
650
|
+
|
|
651
|
+
/**获取上个下标
|
|
652
|
+
* @returns {number} - 上个下标
|
|
653
|
+
*/
|
|
654
|
+
preIndex(): number {
|
|
655
|
+
return this._index - 1;
|
|
656
|
+
}
|
|
657
|
+
|
|
658
|
+
/**判断是否是最后一个
|
|
659
|
+
* @returns {boolean} - 是否是最后一个
|
|
660
|
+
*/
|
|
661
|
+
isLast(): boolean {
|
|
662
|
+
return this._index >= this._list.size() - 1;
|
|
663
|
+
}
|
|
664
|
+
|
|
665
|
+
/**设置数组在迭代器当前下标中的内容
|
|
666
|
+
* 返回自身
|
|
667
|
+
* @param {T} val 要设置的内容
|
|
668
|
+
* @returns {void}
|
|
669
|
+
*/
|
|
670
|
+
set(val: T): SIterator<T> {
|
|
671
|
+
this._list.set(this._index, val);
|
|
672
|
+
return this;
|
|
673
|
+
}
|
|
674
|
+
|
|
675
|
+
/**删除数组在当前下标的内容,然后将下标移至上一位,改变数组长度
|
|
676
|
+
* @returns {T} - 被删除的内容
|
|
677
|
+
*/
|
|
678
|
+
remove(): T {
|
|
679
|
+
let tmp = this._list.get(this._index);
|
|
680
|
+
this._list.remove(this._index);
|
|
681
|
+
this._index--;
|
|
682
|
+
return tmp;
|
|
683
|
+
}
|
|
684
|
+
|
|
685
|
+
/**在当前下标前插入元素,然后将下标移至原元素,即下一位,改变数组长度
|
|
686
|
+
* 返回自身
|
|
687
|
+
* @param {T} obj - 要插入的元素
|
|
688
|
+
* @returns {SIterator<T>} - 自身
|
|
689
|
+
*/
|
|
690
|
+
addPre(obj: T): SIterator<T> {
|
|
691
|
+
this._list.insert(this._index, obj);
|
|
692
|
+
this._index++;
|
|
693
|
+
return this;
|
|
694
|
+
}
|
|
695
|
+
|
|
696
|
+
/**在当前下标后插入元素,然后将下标移至新元素,即下一位,改变数组长度
|
|
697
|
+
* 返回自身
|
|
698
|
+
* @param {T} obj - 要插入的元素
|
|
699
|
+
* @returns {SIterator<T>} - 自身
|
|
700
|
+
*/
|
|
701
|
+
addNext(obj: T): SIterator<T> {
|
|
702
|
+
this._list.insert(this._index + 1, obj);
|
|
703
|
+
this._index++;
|
|
704
|
+
return this;
|
|
705
|
+
}
|
|
706
|
+
}
|
|
707
|
+
|
|
708
|
+
export class SEntry<K, V> {
|
|
709
|
+
private _key: K;
|
|
710
|
+
private _value: V;
|
|
711
|
+
|
|
712
|
+
constructor(key: K, value: V) {
|
|
713
|
+
this._key = key;
|
|
714
|
+
this._value = value;
|
|
715
|
+
}
|
|
716
|
+
getKey() {
|
|
717
|
+
return this._key;
|
|
718
|
+
}
|
|
719
|
+
getValue() {
|
|
720
|
+
return this._value;
|
|
721
|
+
}
|
|
722
|
+
|
|
723
|
+
//重载TypeScript操作符
|
|
724
|
+
get key(): K {
|
|
725
|
+
return this.getKey();
|
|
726
|
+
}
|
|
727
|
+
|
|
728
|
+
get value(): V {
|
|
729
|
+
return this._value;
|
|
730
|
+
}
|
|
731
|
+
}
|
|
732
|
+
export class SHashMap<K, V> {
|
|
733
|
+
private _map: Map<K, V> = new Map();
|
|
734
|
+
|
|
735
|
+
/**构造函数
|
|
736
|
+
* @param {Map<K, V>} [map] - 一个键值对集合
|
|
737
|
+
*/
|
|
738
|
+
constructor(map?: Map<K, V>) {
|
|
739
|
+
if (map == null) return;
|
|
740
|
+
let keys = map.keys();
|
|
741
|
+
for (let key of keys) {
|
|
742
|
+
let value = map.get(key);
|
|
743
|
+
if (value != null) this.put(key, value);
|
|
744
|
+
}
|
|
745
|
+
}
|
|
746
|
+
/**添加一个键值对
|
|
747
|
+
* 返回自身
|
|
748
|
+
* @param {SEntry<K, V>} entry - 键值对
|
|
749
|
+
* @returns {SHashMap<K, V>} - 自身
|
|
750
|
+
*/
|
|
751
|
+
putEntry(entry: SEntry<K, V>): SHashMap<K, V> {
|
|
752
|
+
this._map.set(entry.getKey(), entry.getValue());
|
|
753
|
+
return this;
|
|
754
|
+
}
|
|
755
|
+
|
|
756
|
+
/**获取指定键的值
|
|
757
|
+
* @param {K} key - 键
|
|
758
|
+
* @returns {V | undefined} - 值
|
|
759
|
+
*/
|
|
760
|
+
get(key: K): V | undefined {
|
|
761
|
+
return this._map.get(key);
|
|
762
|
+
}
|
|
763
|
+
|
|
764
|
+
/**添加一个键值对
|
|
765
|
+
* 返回自身
|
|
766
|
+
* @param {K} key - 键
|
|
767
|
+
* @param {V} value - 值
|
|
768
|
+
* @returns {SHashMap<K, V>} - 自身
|
|
769
|
+
*/
|
|
770
|
+
put(key: K, value: V): SHashMap<K, V> {
|
|
771
|
+
this._map.set(key, value);
|
|
772
|
+
return this;
|
|
773
|
+
}
|
|
774
|
+
|
|
775
|
+
/**判断是否存在指定键
|
|
776
|
+
* @param {K} key - 键
|
|
777
|
+
* @returns {boolean} - 是否存在
|
|
778
|
+
*/
|
|
779
|
+
has(key: K): boolean {
|
|
780
|
+
return this._map.has(key);
|
|
781
|
+
}
|
|
782
|
+
|
|
783
|
+
/**获取所有键值对
|
|
784
|
+
* @returns {SList<SEntry<K, V>>} - 键值对列表
|
|
785
|
+
*/
|
|
786
|
+
entrys(): SList<SEntry<K, V>> {
|
|
787
|
+
let list = new SList<SEntry<K, V>>();
|
|
788
|
+
for (const [key, value] of this._map) list.push(new SEntry(key, value));
|
|
789
|
+
return list;
|
|
790
|
+
}
|
|
791
|
+
|
|
792
|
+
/**获取所有键
|
|
793
|
+
* @returns {SList<K>} - 键列表
|
|
794
|
+
*/
|
|
795
|
+
keys(): SList<K> {
|
|
796
|
+
let list = new SList<K>();
|
|
797
|
+
let it = this._map.keys();
|
|
798
|
+
for (let key of it) list.push(key);
|
|
799
|
+
return list;
|
|
800
|
+
}
|
|
801
|
+
|
|
802
|
+
/**获取所有值
|
|
803
|
+
* @returns {SList<V>} - 值列表
|
|
804
|
+
*/
|
|
805
|
+
values(): SList<V> {
|
|
806
|
+
let list = new SList<V>();
|
|
807
|
+
let it = this._map.values();
|
|
808
|
+
for (let val of it) list.push(val);
|
|
809
|
+
return list;
|
|
810
|
+
}
|
|
811
|
+
|
|
812
|
+
/**转换为entry数组,并获取迭代器
|
|
813
|
+
* @returns {SIterator<SEntry<K, V>>} - 迭代器
|
|
814
|
+
*/
|
|
815
|
+
iterator(): SIterator<SEntry<K, V>> {
|
|
816
|
+
return this.entrys().iterator();
|
|
817
|
+
}
|
|
818
|
+
|
|
819
|
+
/**删除指定键的键值对
|
|
820
|
+
* @param {K} key - 键
|
|
821
|
+
* @returns {V | undefined} - 被删除的值
|
|
822
|
+
*/
|
|
823
|
+
remove(key: K): V | undefined {
|
|
824
|
+
let out = this._map.get(key);
|
|
825
|
+
this._map.delete(key);
|
|
826
|
+
return out;
|
|
827
|
+
}
|
|
828
|
+
|
|
829
|
+
/**清空哈希表
|
|
830
|
+
* @returns {SHashMap<K, V>} - 自身
|
|
831
|
+
*/
|
|
832
|
+
clear(): SHashMap<K, V> {
|
|
833
|
+
this._map.clear();
|
|
834
|
+
return this;
|
|
835
|
+
}
|
|
836
|
+
|
|
837
|
+
/**判断哈希表是否为空
|
|
838
|
+
* @returns {boolean} - 是否为空
|
|
839
|
+
*/
|
|
840
|
+
isEmpty(): boolean {
|
|
841
|
+
return this.isEmpty();
|
|
842
|
+
}
|
|
843
|
+
|
|
844
|
+
/**判断是否存在指定值
|
|
845
|
+
* @param {V} val - 值
|
|
846
|
+
* @returns {boolean} - 是否存在
|
|
847
|
+
*/
|
|
848
|
+
containsValue(val: V): boolean {
|
|
849
|
+
return this.values().contains(val);
|
|
850
|
+
}
|
|
851
|
+
|
|
852
|
+
/**判断是否存在指定键
|
|
853
|
+
* @param {K} key - 键
|
|
854
|
+
* @returns {boolean} - 是否存在
|
|
855
|
+
*/
|
|
856
|
+
containsKey(key: K): boolean {
|
|
857
|
+
return this._map.has(key);
|
|
858
|
+
}
|
|
859
|
+
|
|
860
|
+
/**加载指定键的值,若不存在则添加默认值
|
|
861
|
+
* 返回键值
|
|
862
|
+
* @param {K} key - 键
|
|
863
|
+
* @param {V} def - 默认值
|
|
864
|
+
* @returns {V} - 值
|
|
865
|
+
*/
|
|
866
|
+
load(key: K, def: V): V {
|
|
867
|
+
if (this.containsKey(key)) return this.get(key)!;
|
|
868
|
+
this.put(key, def);
|
|
869
|
+
return def;
|
|
870
|
+
}
|
|
871
|
+
|
|
872
|
+
/**合并另一个哈希表,可选择是否覆盖已有键值对
|
|
873
|
+
* @param {SHashMap<K, V>} nmap - 另一个哈希表
|
|
874
|
+
* @param {boolean} [isCover=true] - 是否覆盖已有键值对,默认为 true
|
|
875
|
+
* @returns {SHashMap<K, V>} - 自身
|
|
876
|
+
*/
|
|
877
|
+
merge(nmap: SHashMap<K, V>, isCover: boolean = true): SHashMap<K, V> {
|
|
878
|
+
var it = nmap.iterator();
|
|
879
|
+
while (it.hasNext()) {
|
|
880
|
+
if (isCover) this.putEntry(it.next());
|
|
881
|
+
else {
|
|
882
|
+
var entry = it.next();
|
|
883
|
+
if (!this.containsKey(entry.getKey())) this.putEntry(entry);
|
|
884
|
+
}
|
|
885
|
+
}
|
|
886
|
+
return this;
|
|
887
|
+
}
|
|
888
|
+
|
|
889
|
+
/**获取哈希表大小(键的数量)
|
|
890
|
+
* @returns {number} - 大小
|
|
891
|
+
*/
|
|
892
|
+
size(): number {
|
|
893
|
+
return this._map.size;
|
|
894
|
+
}
|
|
895
|
+
/**对哈希表的每一个键值对进行加工,返回加工完成的键值对组成的新哈希表
|
|
896
|
+
* @param {MapCallback<SEntry<K, V>, SEntry<OK, OV>>} func - 加工函数
|
|
897
|
+
* @returns {SHashMap<OK, OV>} - 新哈希表
|
|
898
|
+
*/
|
|
899
|
+
map<OK, OV>(
|
|
900
|
+
func: MapCallback<SEntry<K, V>, SEntry<OK, OV>>
|
|
901
|
+
): SHashMap<OK, OV> {
|
|
902
|
+
let nmap = new SHashMap<OK, OV>();
|
|
903
|
+
this.entrys()
|
|
904
|
+
.map(func)
|
|
905
|
+
.each((val) => nmap.putEntry(val));
|
|
906
|
+
return nmap;
|
|
907
|
+
}
|
|
908
|
+
|
|
909
|
+
/**返回符合条件的键值对组成的新哈希表
|
|
910
|
+
* @param {FiltCallback<SEntry<K, V>>): boolean} func - 条件函数
|
|
911
|
+
* @returns {SHashMap<K, V>} - 新哈希表
|
|
912
|
+
*/
|
|
913
|
+
filt(func: FiltCallback<SEntry<K, V>>): SHashMap<K, V> {
|
|
914
|
+
let nmap = new SHashMap<K, V>();
|
|
915
|
+
this.entrys()
|
|
916
|
+
.filt(func)
|
|
917
|
+
.each((val) => nmap.putEntry(val));
|
|
918
|
+
return nmap;
|
|
919
|
+
}
|
|
920
|
+
|
|
921
|
+
/**遍历哈希表的每一个键值对
|
|
922
|
+
* @param {EachCallback<SEntry<K, V>>} func - 遍历函数
|
|
923
|
+
* @returns {SHashMap<K, V>} - 自身
|
|
924
|
+
*/
|
|
925
|
+
each(func: EachCallback<SEntry<K, V>>): SHashMap<K, V> {
|
|
926
|
+
this.entrys().each(func);
|
|
927
|
+
return this;
|
|
928
|
+
}
|
|
929
|
+
|
|
930
|
+
/**对哈希表进行统计
|
|
931
|
+
* @param {O} init - 初始值
|
|
932
|
+
* @param {AggrCallback<SEntry<K, V>,O>} func - 统计函数
|
|
933
|
+
* @returns {O} - 统计结果
|
|
934
|
+
*/
|
|
935
|
+
aggr<O>(init: O, func: AggrCallback<SEntry<K, V>, O>): O {
|
|
936
|
+
return this.entrys().aggr(init, func);
|
|
937
|
+
}
|
|
938
|
+
|
|
939
|
+
/**对哈希表进行缩减
|
|
940
|
+
* @param {AggrCallback<SEntry<K, V>,V>} func - 缩减函数
|
|
941
|
+
* @param {V} init - 初始值
|
|
942
|
+
* @returns {V} - 缩减结果
|
|
943
|
+
*/
|
|
944
|
+
reduce(func: AggrCallback<SEntry<K, V>, V>, init?: V): V | null {
|
|
945
|
+
if (this.isEmpty()) {
|
|
946
|
+
if (init === undefined) return null;
|
|
947
|
+
return init;
|
|
948
|
+
}
|
|
949
|
+
|
|
950
|
+
let entries = this.entrys();
|
|
951
|
+
let result: V;
|
|
952
|
+
if (init === undefined) {
|
|
953
|
+
result = entries.get(0).getValue();
|
|
954
|
+
entries.shift();
|
|
955
|
+
} else result = init;
|
|
956
|
+
|
|
957
|
+
entries.each((val, index, list) => {
|
|
958
|
+
result = func(result, val, index, list);
|
|
959
|
+
});
|
|
960
|
+
return result;
|
|
961
|
+
}
|
|
962
|
+
|
|
963
|
+
//重载TypeScript操作符
|
|
964
|
+
[Symbol.iterator]() {
|
|
965
|
+
let it = this.iterator();
|
|
966
|
+
|
|
967
|
+
return {
|
|
968
|
+
next(): { value: SEntry<K, V> | null; done: boolean } {
|
|
969
|
+
if (it.hasNext()) {
|
|
970
|
+
return { value: it.next(), done: false };
|
|
971
|
+
} else {
|
|
972
|
+
return { value: null, done: true };
|
|
973
|
+
}
|
|
974
|
+
},
|
|
975
|
+
};
|
|
976
|
+
}
|
|
977
|
+
}
|
|
978
|
+
|
|
979
|
+
class SKVC {
|
|
980
|
+
private stringMap: SHashMap<string, string> = new SHashMap();
|
|
981
|
+
|
|
982
|
+
constructor() {}
|
|
983
|
+
}
|
|
984
|
+
|
|
985
|
+
/**函数组合器 */
|
|
986
|
+
export class Composer<Result,PreArg = Result> {
|
|
987
|
+
/**组合函数列表 */
|
|
988
|
+
private funcs: Function[] = [];
|
|
989
|
+
private constructor(){};
|
|
990
|
+
/**添加单个参数与返回值不同的函数 */
|
|
991
|
+
public static push<Result,Arg>(func: (arg: Arg) => Result): Composer<Result,Arg>;
|
|
992
|
+
/**添加多个参数与返回值相同的函数 */
|
|
993
|
+
public static push<Result>(func:((arg: Result) => Result), ...funcs: ((arg: Result) => Result)[]): Composer<Result>;
|
|
994
|
+
public static push(...funcs: Function[]){
|
|
995
|
+
const newComposer = new Composer<any>();
|
|
996
|
+
newComposer.funcs = [...funcs];
|
|
997
|
+
return newComposer;
|
|
998
|
+
}
|
|
999
|
+
|
|
1000
|
+
/**添加单个参数与返回值不同的函数 */
|
|
1001
|
+
public push<T>(func: (arg: T) => PreArg): Composer<Result,T>;
|
|
1002
|
+
/**添加多个参数与返回值相同的函数 */
|
|
1003
|
+
public push(func:((arg: Result) => Result), ...funcs: ((arg: PreArg) => PreArg)[]): Composer<Result,PreArg>;
|
|
1004
|
+
public push(...funcs: Function[]): Composer<Result,any> {
|
|
1005
|
+
const newComposer = new Composer<Result>();
|
|
1006
|
+
newComposer.funcs = [...this.funcs, ...funcs];
|
|
1007
|
+
return newComposer;
|
|
1008
|
+
}
|
|
1009
|
+
/**组合函数 */
|
|
1010
|
+
public compose():(arg:PreArg)=>Result {
|
|
1011
|
+
return (arg:PreArg) => this.funcs.reduceRight((value, func) => func(value), arg) as any as Result;
|
|
1012
|
+
}
|
|
1013
|
+
/**直接调用 */
|
|
1014
|
+
public invoke(arg:PreArg):Result {
|
|
1015
|
+
return this.funcs.reduceRight((value, func) => func(value), arg) as any as Result;
|
|
1016
|
+
}
|
|
1017
|
+
}
|
|
1018
|
+
/**函数管道器 */
|
|
1019
|
+
export class Piper<Arg, Result = Arg> {
|
|
1020
|
+
/**管道函数列表 */
|
|
1021
|
+
private funcs: Function[] = [];
|
|
1022
|
+
private constructor(){};
|
|
1023
|
+
/**添加单个参数与返回值不同的函数 */
|
|
1024
|
+
public static pipe<Arg, Result>(func: (arg: Arg) => Result): Piper<Arg, Result>;
|
|
1025
|
+
/**添加多个参数与返回值相同的函数 */
|
|
1026
|
+
public static pipe<Arg>(func:((arg: Arg) => Arg), ...funcs: ((arg: Arg) => Arg)[]): Piper<Arg>;
|
|
1027
|
+
public static pipe(...funcs: Function[]){
|
|
1028
|
+
const newPiper = new Piper<any>();
|
|
1029
|
+
newPiper.funcs = [...funcs];
|
|
1030
|
+
return newPiper;
|
|
1031
|
+
}
|
|
1032
|
+
|
|
1033
|
+
/**添加单个参数与返回值不同的函数 */
|
|
1034
|
+
public pipe<T>(func: (arg: Result) => T): Piper<Arg, T>;
|
|
1035
|
+
/**添加多个参数与返回值相同的函数 */
|
|
1036
|
+
public pipe(func:((arg: Result) => Result), ...funcs: ((arg: Result) => Result)[]): Piper<Arg, Result>;
|
|
1037
|
+
public pipe(...funcs: Function[]): Piper<Arg, any> {
|
|
1038
|
+
const newPiper = new Piper<Arg>();
|
|
1039
|
+
newPiper.funcs = [...this.funcs, ...funcs];
|
|
1040
|
+
return newPiper;
|
|
1041
|
+
}
|
|
1042
|
+
/**管道函数 */
|
|
1043
|
+
public pipeline():(arg:Arg)=>Result {
|
|
1044
|
+
return (arg:Arg) => this.funcs.reduce((value, func) => func(value), arg) as any as Result;
|
|
1045
|
+
}
|
|
1046
|
+
/**直接调用 */
|
|
1047
|
+
public invoke(arg:Arg):Result {
|
|
1048
|
+
return this.funcs.reduce((value, func) => func(value), arg) as any as Result;
|
|
1049
|
+
}
|
|
1050
|
+
}
|
|
1051
|
+
|