semantic-typescript 0.0.8 → 0.1.4
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/semantic.d.ts +22 -5
- package/dist/semantic.js +106 -52
- package/package.json +53 -8
- package/readme.cn.md +343 -446
- package/readme.de.md +341 -443
- package/readme.es.md +342 -443
- package/readme.fr.md +345 -446
- package/readme.jp.md +346 -448
- package/readme.kr.md +350 -452
- package/readme.md +345 -448
- package/readme.ru.md +347 -448
- package/readme.tw.md +340 -443
package/readme.cn.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Semantic-TypeScript
|
|
1
|
+
# Semantic-TypeScript 流处理库
|
|
2
2
|
|
|
3
3
|
## 简介
|
|
4
4
|
|
|
@@ -6,524 +6,421 @@ Semantic-TypeScript 是一个受到 JavaScript GeneratorFunction、Java Stream
|
|
|
6
6
|
|
|
7
7
|
与传统的同步处理不同,Semantic 采用异步处理模式。在创建数据流时,终端接收数据的时间完全取决于上游何时调用 `accept` 和 `interrupt` 回调函数,这种设计使得库能够优雅地处理实时数据流、大型数据集和异步数据源。
|
|
8
8
|
|
|
9
|
-
##
|
|
9
|
+
## 安装
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
| **函数式编程** | 不可变数据结构和纯函数 | 代码更可预测,易于测试和维护 |
|
|
15
|
-
| **惰性求值** | 按需计算,优化性能 | 处理大型数据集时内存效率高 |
|
|
16
|
-
| **异步流处理** | 基于 Generator 的异步数据流 | 适合实时数据和事件驱动场景 |
|
|
17
|
-
| **多范式收集器** | 有序、无序、统计等多种收集策略 | 根据不同场景选择最优策略 |
|
|
18
|
-
| **统计分析** | 内置完整的统计计算功能 | 数据分析和报表生成一体化 |
|
|
19
|
-
|
|
20
|
-
## 性能注意事项
|
|
21
|
-
|
|
22
|
-
**重要提醒**:以下方法会通过牺牲性能来收集和排序数据,得到有序的数据集合:
|
|
23
|
-
- `toOrdered()`
|
|
24
|
-
- `toWindow()`
|
|
25
|
-
- `toNumericStatistics()`
|
|
26
|
-
- `toBigIntStatistics()`
|
|
27
|
-
- `sorted()`
|
|
28
|
-
- `sorted(comparator)`
|
|
29
|
-
|
|
30
|
-
特别需要注意的是,`sorted()` 和 `sorted(comparator)` 会覆盖以下方法的结果:
|
|
31
|
-
- `redirect(redirector)`
|
|
32
|
-
- `translate(translator)`
|
|
33
|
-
- `shuffle(mapper)`
|
|
34
|
-
|
|
35
|
-
## 工厂方法
|
|
36
|
-
|
|
37
|
-
### 流创建工厂
|
|
11
|
+
```bash
|
|
12
|
+
npm install semantic-typescript
|
|
13
|
+
```
|
|
38
14
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
|
42
|
-
|
|
43
|
-
| `
|
|
44
|
-
| `
|
|
45
|
-
| `
|
|
46
|
-
| `
|
|
47
|
-
| `
|
|
15
|
+
## 基础类型
|
|
16
|
+
|
|
17
|
+
| 类型 | 描述 |
|
|
18
|
+
|------|------|
|
|
19
|
+
| `Invalid<T>` | 扩展 null 或 undefined 的类型 |
|
|
20
|
+
| `Valid<T>` | 排除 null 和 undefined 的类型 |
|
|
21
|
+
| `MaybeInvalid<T>` | 可能为 null 或 undefined 的类型 |
|
|
22
|
+
| `Primitive` | 原始类型集合 |
|
|
23
|
+
| `MaybePrimitive<T>` | 可能为原始类型的类型 |
|
|
24
|
+
| `OptionalSymbol` | Optional 类的符号标识 |
|
|
25
|
+
| `SemanticSymbol` | Semantic 类的符号标识 |
|
|
26
|
+
| `CollectorsSymbol` | Collector 类的符号标识 |
|
|
27
|
+
| `CollectableSymbol` | Collectable 类的符号标识 |
|
|
28
|
+
| `OrderedCollectableSymbol` | OrderedCollectable 类的符号标识 |
|
|
29
|
+
| `WindowCollectableSymbol` | WindowCollectable 类的符号标识 |
|
|
30
|
+
| `StatisticsSymbol` | Statistics 类的符号标识 |
|
|
31
|
+
| `NumericStatisticsSymbol` | NumericStatistics 类的符号标识 |
|
|
32
|
+
| `BigIntStatisticsSymbol` | BigIntStatistics 类的符号标识 |
|
|
33
|
+
| `UnorderedCollectableSymbol` | UnorderedCollectable 类的符号标识 |
|
|
34
|
+
| `Runnable` | 无参数无返回值的函数 |
|
|
35
|
+
| `Supplier<R>` | 无参数返回 R 的函数 |
|
|
36
|
+
| `Functional<T, R>` | 单参数转换函数 |
|
|
37
|
+
| `Predicate<T>` | 单参数判断函数 |
|
|
38
|
+
| `BiFunctional<T, U, R>` | 双参数转换函数 |
|
|
39
|
+
| `BiPredicate<T, U>` | 双参数判断函数 |
|
|
40
|
+
| `Comparator<T>` | 比较函数 |
|
|
41
|
+
| `TriFunctional<T, U, V, R>` | 三参数转换函数 |
|
|
42
|
+
| `Consumer<T>` | 单参数消费函数 |
|
|
43
|
+
| `BiConsumer<T, U>` | 双参数消费函数 |
|
|
44
|
+
| `TriConsumer<T, U, V>` | 三参数消费函数 |
|
|
45
|
+
| `Generator<T>` | 生成器函数 |
|
|
48
46
|
|
|
49
|
-
**代码示例补充:**
|
|
50
47
|
```typescript
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
const
|
|
55
|
-
|
|
56
|
-
// 创建数值范围流
|
|
57
|
-
const rangeStream = range(1, 10, 2); // 1, 3, 5, 7, 9
|
|
58
|
-
|
|
59
|
-
// 填充重复元素
|
|
60
|
-
const filledStream = fill("hello", 3n); // "hello", "hello", "hello"
|
|
61
|
-
|
|
62
|
-
// 创建空流
|
|
63
|
-
const emptyStream = empty<number>();
|
|
48
|
+
// 类型使用示例
|
|
49
|
+
const predicate: Predicate<number> = (n) => n > 0;
|
|
50
|
+
const mapper: Functional<string, number> = (str) => str.length;
|
|
51
|
+
const comparator: Comparator<number> = (a, b) => a - b;
|
|
64
52
|
```
|
|
65
53
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
|
69
|
-
|
|
70
|
-
| `validate
|
|
71
|
-
| `invalidate
|
|
72
|
-
| `
|
|
73
|
-
| `
|
|
54
|
+
## 类型守卫
|
|
55
|
+
|
|
56
|
+
| 函数 | 描述 | 时间复杂度 | 空间复杂度 |
|
|
57
|
+
|------|------|------------|------------|
|
|
58
|
+
| `validate<T>(t: MaybeInvalid<T>): t is T` | 验证值不为 null 或 undefined | O(1) | O(1) |
|
|
59
|
+
| `invalidate<T>(t: MaybeInvalid<T>): t is null \| undefined` | 验证值为 null 或 undefined | O(1) | O(1) |
|
|
60
|
+
| `isBoolean(t: unknown): t is boolean` | 检查是否为布尔值 | O(1) | O(1) |
|
|
61
|
+
| `isString(t: unknown): t is string` | 检查是否为字符串 | O(1) | O(1) |
|
|
62
|
+
| `isNumber(t: unknown): t is number` | 检查是否为数字 | O(1) | O(1) |
|
|
63
|
+
| `isFunction(t: unknown): t is Function` | 检查是否为函数 | O(1) | O(1) |
|
|
64
|
+
| `isObject(t: unknown): t is object` | 检查是否为对象 | O(1) | O(1) |
|
|
65
|
+
| `isSymbol(t: unknown): t is symbol` | 检查是否为 Symbol | O(1) | O(1) |
|
|
66
|
+
| `isBigint(t: unknown): t is bigint` | 检查是否为 BigInt | O(1) | O(1) |
|
|
67
|
+
| `isPrimitive(t: unknown): t is Primitive` | 检查是否为原始类型 | O(1) | O(1) |
|
|
68
|
+
| `isIterable(t: unknown): t is Iterable<unknown>` | 检查是否为可迭代对象 | O(1) | O(1) |
|
|
69
|
+
| `isOptional(t: unknown): t is Optional<unknown>` | 检查是否为 Optional 实例 | O(1) | O(1) |
|
|
70
|
+
| `isSemantic(t: unknown): t is Semantic<unknown>` | 检查是否为 Semantic 实例 | O(1) | O(1) |
|
|
71
|
+
| `isCollector(t: unknown): t is Collector<unknown, unknown, unknown>` | 检查是否为 Collector 实例 | O(1) | O(1) |
|
|
72
|
+
| `isCollectable(t: unknown): t is Collectable<unknown>` | 检查是否为 Collectable 实例 | O(1) | O(1) |
|
|
73
|
+
| `isOrderedCollectable(t: unknown): t is OrderedCollectable<unknown>` | 检查是否为 OrderedCollectable 实例 | O(1) | O(1) |
|
|
74
|
+
| `isWindowCollectable(t: unknown): t is WindowCollectable<unknown>` | 检查是否为 WindowCollectable 实例 | O(1) | O(1) |
|
|
75
|
+
| `isUnorderedCollectable(t: unknown): t is UnorderedCollectable<unknown>` | 检查是否为 UnorderedCollectable 实例 | O(1) | O(1) |
|
|
76
|
+
| `isStatistics(t: unknown): t is Statistics<unknown, number \| bigint>` | 检查是否为 Statistics 实例 | O(1) | O(1) |
|
|
77
|
+
| `isNumericStatistics(t: unknown): t is NumericStatistics<unknown>` | 检查是否为 NumericStatistics 实例 | O(1) | O(1) |
|
|
78
|
+
| `isBigIntStatistics(t: unknown): t is BigIntStatistics<unknown>` | 检查是否为 BigIntStatistics 实例 | O(1) | O(1) |
|
|
74
79
|
|
|
75
|
-
**代码示例补充:**
|
|
76
80
|
```typescript
|
|
77
|
-
|
|
81
|
+
// 类型守卫使用示例
|
|
82
|
+
const value: unknown = "hello";
|
|
78
83
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
if (validate(data)) {
|
|
82
|
-
console.log(data.toUpperCase()); // 安全调用,因为 validate 确保了 data 不为 null
|
|
84
|
+
if (isString(value)) {
|
|
85
|
+
console.log(value.length); // 类型安全,value 被推断为 string
|
|
83
86
|
}
|
|
84
87
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
console.log("数据无效"); // 会执行,因为 invalidate 检测到 null
|
|
88
|
+
if (isOptional(someValue)) {
|
|
89
|
+
someValue.ifPresent(val => console.log(val));
|
|
88
90
|
}
|
|
89
|
-
|
|
90
|
-
// 比较值
|
|
91
|
-
const comparison = useCompare("apple", "banana"); // -1
|
|
92
|
-
|
|
93
|
-
// 生成随机数
|
|
94
|
-
const randomNum = useRandom(42); // 基于种子 42 的随机数
|
|
95
91
|
```
|
|
96
92
|
|
|
97
|
-
##
|
|
98
|
-
|
|
99
|
-
### Optional<T> - 安全空值处理
|
|
100
|
-
|
|
101
|
-
Optional 类提供了一种安全处理可能为 null 或 undefined 值的函数式方法。
|
|
93
|
+
## 工具函数
|
|
102
94
|
|
|
103
|
-
|
|
|
104
|
-
|
|
105
|
-
| `
|
|
106
|
-
| `
|
|
107
|
-
| `getOrDefault(defaultValue: T)` | `T` | 获取值或默认值 | O(1) |
|
|
108
|
-
| `ifPresent(action: Consumer<T>)` | `void` | 值存在时执行操作 | O(1) |
|
|
109
|
-
| `isEmpty()` | `boolean` | 检查是否为空 | O(1) |
|
|
110
|
-
| `isPresent()` | `boolean` | 检查是否有值 | O(1) |
|
|
111
|
-
| `map<R>(mapper: Functional<T, R>)` | `Optional<R>` | 映射转换值 | O(1) |
|
|
112
|
-
| `static of<T>(value: MaybeInvalid<T>)` | `Optional<T>` | 创建 Optional 实例 | O(1) |
|
|
113
|
-
| `static ofNullable<T>(value?)` | `Optional<T>` | 创建可空的 Optional | O(1) |
|
|
114
|
-
| `static ofNonNull<T>(value: T)` | `Optional<T>` | 创建非空 Optional | O(1) |
|
|
95
|
+
| 函数 | 描述 | 时间复杂度 | 空间复杂度 |
|
|
96
|
+
|------|------|------------|------------|
|
|
97
|
+
| `useCompare<T>(t1: T, t2: T): number` | 通用比较函数 | O(1) | O(1) |
|
|
98
|
+
| `useRandom<T = number \| bigint>(index: T): T` | 伪随机数生成器 | O(log n) | O(1) |
|
|
115
99
|
|
|
116
|
-
**代码示例补充:**
|
|
117
100
|
```typescript
|
|
118
|
-
|
|
101
|
+
// 工具函数使用示例
|
|
102
|
+
const numbers = [3, 1, 4, 1, 5];
|
|
103
|
+
numbers.sort(useCompare); // [1, 1, 3, 4, 5]
|
|
119
104
|
|
|
120
|
-
|
|
121
|
-
const
|
|
105
|
+
const randomNum = useRandom(42); // 基于种子的随机数
|
|
106
|
+
const randomBigInt = useRandom(1000n); // BigInt 随机数
|
|
107
|
+
```
|
|
122
108
|
|
|
123
|
-
|
|
124
|
-
const result = optionalValue
|
|
125
|
-
.filter(val => val.length > 3) // 过滤长度大于3的值
|
|
126
|
-
.map(val => val.toUpperCase()) // 转换为大写
|
|
127
|
-
.getOrDefault("default"); // 获取值或默认值
|
|
109
|
+
## 工厂方法
|
|
128
110
|
|
|
129
|
-
|
|
111
|
+
### Optional 工厂方法
|
|
130
112
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
113
|
+
| 方法 | 描述 | 时间复杂度 | 空间复杂度 |
|
|
114
|
+
|------|------|------------|------------|
|
|
115
|
+
| `Optional.empty<T>()` | 创建空的 Optional | O(1) | O(1) |
|
|
116
|
+
| `Optional.of<T>(value)` | 创建包含值的 Optional | O(1) | O(1) |
|
|
117
|
+
| `Optional.ofNullable<T>(value)` | 创建可能为空的 Optional | O(1) | O(1) |
|
|
118
|
+
| `Optional.ofNonNull<T>(value)` | 创建非空的 Optional | O(1) | O(1) |
|
|
135
119
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
120
|
+
```typescript
|
|
121
|
+
// Optional 使用示例
|
|
122
|
+
const emptyOpt = Optional.empty<number>();
|
|
123
|
+
const presentOpt = Optional.of(42);
|
|
124
|
+
const nullableOpt = Optional.ofNullable<string>(null);
|
|
125
|
+
const nonNullOpt = Optional.ofNonNull("hello");
|
|
126
|
+
|
|
127
|
+
presentOpt.ifPresent(val => console.log(val)); // 输出 42
|
|
128
|
+
console.log(emptyOpt.orElse(100)); // 输出 100
|
|
142
129
|
```
|
|
143
130
|
|
|
144
|
-
###
|
|
145
|
-
|
|
146
|
-
Semantic 是核心的流处理类,提供丰富的流操作符。
|
|
147
|
-
|
|
148
|
-
#### 流转换操作
|
|
149
|
-
|
|
150
|
-
| 方法 | 返回类型 | 描述 | 性能影响 |
|
|
151
|
-
|------|----------|------|----------|
|
|
152
|
-
| `concat(other: Semantic<E>)` | `Semantic<E>` | 连接两个流 | O(n+m) |
|
|
153
|
-
| `distinct()` | `Semantic<E>` | 去重(使用 Set) | O(n) |
|
|
154
|
-
| `distinct(comparator)` | `Semantic<E>` | 自定义比较器去重 | O(n²) |
|
|
155
|
-
| `dropWhile(predicate)` | `Semantic<E>` | 丢弃满足条件的起始元素 | O(n) |
|
|
156
|
-
| `filter(predicate)` | `Semantic<E>` | 过滤元素 | O(n) |
|
|
157
|
-
| `flat(mapper)` | `Semantic<E>` | 扁平化嵌套流 | O(n×m) |
|
|
158
|
-
| `flatMap(mapper)` | `Semantic<R>` | 映射并扁平化 | O(n×m) |
|
|
159
|
-
| `limit(n)` | `Semantic<E>` | 限制元素数量 | O(n) |
|
|
160
|
-
| `map(mapper)` | `Semantic<R>` | 映射转换元素 | O(n) |
|
|
161
|
-
| `peek(consumer)` | `Semantic<E>` | 查看元素而不修改 | O(n) |
|
|
162
|
-
| `redirect(redirector)` | `Semantic<E>` | 重定向索引 | O(n) |
|
|
163
|
-
| `reverse()` | `Semantic<E>` | 反转流顺序 | O(n) |
|
|
164
|
-
| `shuffle()` | `Semantic<E>` | 随机打乱顺序 | O(n) |
|
|
165
|
-
| `shuffle(mapper)` | `Semantic<E>` | 自定义打乱逻辑 | O(n) |
|
|
166
|
-
| `skip(n)` | `Semantic<E>` | 跳过前n个元素 | O(n) |
|
|
167
|
-
| `sub(start, end)` | `Semantic<E>` | 获取子流 | O(n) |
|
|
168
|
-
| `takeWhile(predicate)` | `Semantic<E>` | 获取满足条件的起始元素 | O(n) |
|
|
169
|
-
| `translate(offset)` | `Semantic<E>` | 平移索引 | O(n) |
|
|
170
|
-
| `translate(translator)` | `Semantic<E>` | 自定义索引变换 | O(n) |
|
|
171
|
-
|
|
172
|
-
**代码示例补充:**
|
|
173
|
-
```typescript
|
|
174
|
-
import { from } from 'semantic-typescript';
|
|
131
|
+
### Collector 工厂方法
|
|
175
132
|
|
|
176
|
-
|
|
133
|
+
| 方法 | 描述 | 时间复杂度 | 空间复杂度 |
|
|
134
|
+
|------|------|------------|------------|
|
|
135
|
+
| `Collector.full(identity, accumulator, finisher)` | 创建完整收集器 | O(1) | O(1) |
|
|
136
|
+
| `Collector.shortable(identity, interruptor, accumulator, finisher)` | 创建可中断收集器 | O(1) | O(1) |
|
|
177
137
|
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
138
|
+
```typescript
|
|
139
|
+
// Collector 使用示例
|
|
140
|
+
const sumCollector = Collector.full(
|
|
141
|
+
() => 0,
|
|
142
|
+
(sum, num) => sum + num,
|
|
143
|
+
result => result
|
|
144
|
+
);
|
|
185
145
|
|
|
186
|
-
|
|
146
|
+
const numbers = from([1, 2, 3, 4, 5]);
|
|
147
|
+
const total = numbers.toUnoredered().collect(sumCollector); // 15
|
|
187
148
|
```
|
|
188
149
|
|
|
189
|
-
|
|
150
|
+
### Semantic 工厂方法
|
|
190
151
|
|
|
191
|
-
| 方法 |
|
|
192
|
-
|
|
193
|
-
| `
|
|
194
|
-
| `
|
|
195
|
-
| `
|
|
196
|
-
| `
|
|
197
|
-
| `
|
|
198
|
-
| `
|
|
199
|
-
| `
|
|
152
|
+
| 方法 | 描述 | 时间复杂度 | 空间复杂度 |
|
|
153
|
+
|------|------|------------|------------|
|
|
154
|
+
| `blob(blob, chunkSize)` | 从 Blob 创建流 | O(n) | O(chunkSize) |
|
|
155
|
+
| `empty<E>()` | 创建空流 | O(1) | O(1) |
|
|
156
|
+
| `fill<E>(element, count)` | 创建填充流 | O(n) | O(1) |
|
|
157
|
+
| `from<E>(iterable)` | 从可迭代对象创建流 | O(1) | O(1) |
|
|
158
|
+
| `interval(period, delay?)` | 创建定时间隔流 | O(1)* | O(1) |
|
|
159
|
+
| `iterate<E>(generator)` | 从生成器创建流 | O(1) | O(1) |
|
|
160
|
+
| `range(start, end, step)` | 创建数值范围流 | O(n) | O(1) |
|
|
161
|
+
| `websocket(websocket)` | 从 WebSocket 创建流 | O(1) | O(1) |
|
|
200
162
|
|
|
201
|
-
**代码示例补充:**
|
|
202
163
|
```typescript
|
|
203
|
-
|
|
164
|
+
// Semantic 工厂方法使用示例
|
|
204
165
|
|
|
205
|
-
|
|
166
|
+
// 从 Blob 创建流(分块读取)
|
|
167
|
+
blob(someBlob, 1024n)
|
|
168
|
+
.toUnordered()
|
|
169
|
+
.write(WritableStream)
|
|
170
|
+
.then(callback) // 写入流成功
|
|
171
|
+
.catch(writeFi); // 写入流失败
|
|
206
172
|
|
|
207
|
-
//
|
|
208
|
-
|
|
173
|
+
// 创建空流,在拼接其它流之前不会执行
|
|
174
|
+
empty<string>()
|
|
175
|
+
.toUnordered()
|
|
176
|
+
.join(); //[]
|
|
209
177
|
|
|
210
|
-
//
|
|
211
|
-
const
|
|
178
|
+
// 创建填充流
|
|
179
|
+
const filledStream = fill("hello", 3); // "hello", "hello", "hello"
|
|
212
180
|
|
|
213
|
-
//
|
|
214
|
-
const
|
|
181
|
+
// 创建初始延迟2秒、执行周期5秒的时序流,基于计时器机制实现,因系统调度精度限制可能存在时间漂移。
|
|
182
|
+
const intervalStream = interval(5000, 2000);
|
|
215
183
|
|
|
216
|
-
//
|
|
217
|
-
const
|
|
184
|
+
// 从可迭代对象创建流
|
|
185
|
+
const numberStream = from([1, 2, 3, 4, 5]);
|
|
186
|
+
const stringStream = from(new Set(["Alex", "Bob"]));
|
|
218
187
|
|
|
219
|
-
//
|
|
220
|
-
const
|
|
188
|
+
// 创建范围流
|
|
189
|
+
const rangeStream = range(1, 10, 2); // 1, 3, 5, 7, 9
|
|
221
190
|
|
|
222
|
-
//
|
|
191
|
+
// WebSocket 事件流
|
|
192
|
+
const ws = new WebSocket("ws://localhost:8080");
|
|
193
|
+
websocket(ws)
|
|
194
|
+
.filter((event)=> event.type === "message"); //只监听消息事件
|
|
195
|
+
.toUnordered() // 对于事件一般不排序
|
|
196
|
+
.forEach((event)=> receive(event)); //接收消息
|
|
223
197
|
```
|
|
224
198
|
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
199
|
+
## Semantic 类方法
|
|
200
|
+
|
|
201
|
+
| 方法 | 描述 | 时间复杂度 | 空间复杂度 |
|
|
202
|
+
|------|------|------------|------------|
|
|
203
|
+
| `concat(other)` | 连接两个流 | O(n) | O(1) |
|
|
204
|
+
| `distinct()` | 去重 | O(n) | O(n) |
|
|
205
|
+
| `distinct(comparator)` | 使用比较器去重 | O(n²) | O(n) |
|
|
206
|
+
| `dropWhile(predicate)` | 丢弃满足条件的元素 | O(n) | O(1) |
|
|
207
|
+
| `filter(predicate)` | 过滤元素 | O(n) | O(1) |
|
|
208
|
+
| `flat(mapper)` | 扁平化映射 | O(n × m) | O(1) |
|
|
209
|
+
| `flatMap(mapper)` | 扁平化映射到新类型 | O(n × m) | O(1) |
|
|
210
|
+
| `limit(n)` | 限制元素数量 | O(n) | O(1) |
|
|
211
|
+
| `map(mapper)` | 映射转换 | O(n) | O(1) |
|
|
212
|
+
| `peek(consumer)` | 查看元素 | O(n) | O(1) |
|
|
213
|
+
| `redirect(redirector)` | 重定向索引 | O(n) | O(1) |
|
|
214
|
+
| `reverse()` | 反转流 | O(n) | O(1) |
|
|
215
|
+
| `shuffle()` | 随机打乱 | O(n) | O(1) |
|
|
216
|
+
| `shuffle(mapper)` | 使用映射器打乱 | O(n) | O(1) |
|
|
217
|
+
| `skip(n)` | 跳过前n个元素 | O(n) | O(1) |
|
|
218
|
+
| `sorted()` | 排序 | O(n log n) | O(n) |
|
|
219
|
+
| `sorted(comparator)` | 使用比较器排序 | O(n log n) | O(n) |
|
|
220
|
+
| `sub(start, end)` | 获取子流 | O(n) | O(1) |
|
|
221
|
+
| `takeWhile(predicate)` | 获取满足条件的元素 | O(n) | O(1) |
|
|
222
|
+
| `translate(offset)` | 平移索引 | O(n) | O(1) |
|
|
223
|
+
| `translate(translator)` | 使用转换器平移索引 | O(n) | O(1) |
|
|
228
224
|
|
|
229
|
-
| 方法 | 描述 | 使用场景 |
|
|
230
|
-
|------|------|----------|
|
|
231
|
-
| `collect(generator)` | 执行数据收集 | 流终止操作 |
|
|
232
|
-
| `static full(identity, accumulator, finisher)` | 创建完整收集器 | 需要完整处理 |
|
|
233
|
-
| `static shortable(identity, interruptor, accumulator, finisher)` | 创建可中断收集器 | 可能提前终止 |
|
|
234
|
-
|
|
235
|
-
**代码示例补充:**
|
|
236
225
|
```typescript
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
//
|
|
240
|
-
|
|
241
|
-
()
|
|
242
|
-
(
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
//
|
|
247
|
-
const
|
|
248
|
-
|
|
226
|
+
// Semantic 操作示例
|
|
227
|
+
const result = from([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
|
|
228
|
+
.filter(n => n % 2 === 0) // 过滤偶数
|
|
229
|
+
.map(n => n * 2) // 乘以2
|
|
230
|
+
.skip(1) // 跳过第一个
|
|
231
|
+
.limit(3) // 限制3个元素
|
|
232
|
+
.toArray(); // 转换为数组
|
|
233
|
+
// 结果: [8, 12, 20]
|
|
234
|
+
|
|
235
|
+
// 复杂操作示例
|
|
236
|
+
const complexResult = range(1, 100, 1)
|
|
237
|
+
.flatMap(n => from([n, n * 2])) // 每个元素映射为两个
|
|
238
|
+
.distinct() // 去重
|
|
239
|
+
.shuffle() // 打乱顺序
|
|
240
|
+
.takeWhile(n => n < 50) // 取小于50的元素
|
|
241
|
+
.toOrdered() // 转换为有序收集器
|
|
242
|
+
.toArray(); // 转换为数组
|
|
249
243
|
```
|
|
250
244
|
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
提供丰富的数据聚合和转换方法。**注意:必须先通过 Semantic 实例调用 sorted(), toOrdered() 等方法得到 Collectable 实例后才能使用以下方法。**
|
|
245
|
+
## 收集器转换方法
|
|
254
246
|
|
|
255
|
-
|
|
247
|
+
| 方法 | 描述 | 时间复杂度 | 空间复杂度 |
|
|
248
|
+
|------|------|------------|------------|
|
|
249
|
+
| `toUnoredered()` | 转换为无序收集器(性能优先) | O(1) | O(1) |
|
|
250
|
+
| `toOrdered()` | 转换为有序收集器 | O(1) | O(1) |
|
|
251
|
+
| `sorted()` | 排序并转换为有序收集器 | O(n log n) | O(n) |
|
|
252
|
+
| `toWindow()` | 转换为窗口收集器 | O(1) | O(1) |
|
|
253
|
+
| `toNumericStatistics()` | 转换为数值统计 | O(1) | O(1) |
|
|
254
|
+
| `toBigintStatistics()` | 转换为大数统计 | O(1) | O(1) |
|
|
256
255
|
|
|
257
|
-
| 方法 | 返回类型 | 描述 | 示例 |
|
|
258
|
-
|------|----------|------|------|
|
|
259
|
-
| `anyMatch(predicate)` | `boolean` | 是否存在匹配元素 | `anyMatch(x => x > 0)` |
|
|
260
|
-
| `allMatch(predicate)` | `boolean` | 是否所有元素匹配 | `allMatch(x => x > 0)` |
|
|
261
|
-
| `count()` | `bigint` | 元素数量统计 | `count()` → `5n` |
|
|
262
|
-
| `isEmpty()` | `boolean` | 是否为空流 | `isEmpty()` |
|
|
263
|
-
| `findAny()` | `Optional<E>` | 查找任意元素 | `findAny()` |
|
|
264
|
-
| `findFirst()` | `Optional<E>` | 查找第一个元素 | `findFirst()` |
|
|
265
|
-
| `findLast()` | `Optional<E>` | 查找最后一个元素 | `findLast()` |
|
|
266
|
-
|
|
267
|
-
**代码示例补充:**
|
|
268
256
|
```typescript
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
const
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
257
|
+
// 收集器转换示例
|
|
258
|
+
const numbers = from([3, 1, 4, 1, 5, 9, 2, 6, 5]);
|
|
259
|
+
|
|
260
|
+
// 性能优先:使用无序收集器
|
|
261
|
+
const unordered = numbers
|
|
262
|
+
.filter(n => n > 3)
|
|
263
|
+
.toUnoredered();
|
|
264
|
+
|
|
265
|
+
// 需要排序:使用有序收集器
|
|
266
|
+
const ordered = numbers
|
|
267
|
+
.sorted()
|
|
268
|
+
.toOrdered();
|
|
269
|
+
|
|
270
|
+
// 统计分析:使用统计收集器
|
|
271
|
+
const stats = numbers
|
|
272
|
+
.toNumericStatistics();
|
|
273
|
+
|
|
274
|
+
console.log(stats.mean()); // 平均值
|
|
275
|
+
console.log(stats.median()); // 中位数
|
|
276
|
+
console.log(stats.standardDeviation()); // 标准差
|
|
277
|
+
|
|
278
|
+
// 窗口操作
|
|
279
|
+
const windowed = numbers
|
|
280
|
+
.toWindow()
|
|
281
|
+
.tumble(3n); // 每3个元素一个窗口
|
|
282
|
+
|
|
283
|
+
windowed.forEach(window => {
|
|
284
|
+
console.log(window.toArray()); // 每个窗口的内容
|
|
285
|
+
});
|
|
283
286
|
```
|
|
284
287
|
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
| 方法 |
|
|
288
|
-
|
|
289
|
-
| `
|
|
290
|
-
| `
|
|
291
|
-
| `
|
|
292
|
-
| `
|
|
293
|
-
| `
|
|
294
|
-
| `
|
|
295
|
-
| `
|
|
296
|
-
| `
|
|
297
|
-
| `
|
|
298
|
-
| `
|
|
299
|
-
| `
|
|
300
|
-
|
|
301
|
-
|
|
288
|
+
## Collectable 收集方法
|
|
289
|
+
|
|
290
|
+
| 方法 | 描述 | 时间复杂度 | 空间复杂度 |
|
|
291
|
+
|------|------|------------|------------|
|
|
292
|
+
| `anyMatch(predicate)` | 是否存在匹配元素 | O(n) | O(1) |
|
|
293
|
+
| `allMatch(predicate)` | 是否所有元素匹配 | O(n) | O(1) |
|
|
294
|
+
| `count()` | 元素计数 | O(n) | O(1) |
|
|
295
|
+
| `isEmpty()` | 是否为空 | O(1) | O(1) |
|
|
296
|
+
| `findAny()` | 查找任意元素 | O(n) | O(1) |
|
|
297
|
+
| `findFirst()` | 查找第一个元素 | O(n) | O(1) |
|
|
298
|
+
| `findLast()` | 查找最后一个元素 | O(n) | O(1) |
|
|
299
|
+
| `forEach(action)` | 遍历所有元素 | O(n) | O(1) |
|
|
300
|
+
| `group(classifier)` | 按分类器分组 | O(n) | O(n) |
|
|
301
|
+
| `groupBy(keyExtractor, valueExtractor)` | 按键值提取器分组 | O(n) | O(n) |
|
|
302
|
+
| `join()` | 连接为字符串 | O(n) | O(n) |
|
|
303
|
+
| `join(delimiter)` | 使用分隔符连接 | O(n) | O(n) |
|
|
304
|
+
| `nonMatch(predicate)` | 是否没有元素匹配 | O(n) | O(1) |
|
|
305
|
+
| `partition(count)` | 按数量分区 | O(n) | O(n) |
|
|
306
|
+
| `partitionBy(classifier)` | 按分类器分区 | O(n) | O(n) |
|
|
307
|
+
| `reduce(accumulator)` | 归约操作 | O(n) | O(1) |
|
|
308
|
+
| `reduce(identity, accumulator)` | 带初始值的归约 | O(n) | O(1) |
|
|
309
|
+
| `toArray()` | 转换为数组 | O(n) | O(n) |
|
|
310
|
+
| `toMap(keyExtractor, valueExtractor)` | 转换为Map | O(n) | O(n) |
|
|
311
|
+
| `toSet()` | 转换为Set | O(n) | O(n) |
|
|
312
|
+
| `write(stream)` | 写入流 | O(n) | O(1) |
|
|
313
|
+
|
|
302
314
|
```typescript
|
|
303
|
-
|
|
315
|
+
// Collectable 操作示例
|
|
316
|
+
const data = from([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
|
|
317
|
+
.filter(n => n % 2 === 0)
|
|
318
|
+
.toOrdered();
|
|
304
319
|
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
{ name: "Charlie", age: 25, city: "New York" }
|
|
309
|
-
]);
|
|
320
|
+
// 匹配检查
|
|
321
|
+
console.log(data.anyMatch(n => n > 5)); // true
|
|
322
|
+
console.log(data.allMatch(n => n < 20)); // true
|
|
310
323
|
|
|
311
|
-
//
|
|
312
|
-
|
|
324
|
+
// 查找操作
|
|
325
|
+
data.findFirst().ifPresent(n => console.log(n)); // 2
|
|
326
|
+
data.findAny().ifPresent(n => console.log(n)); // 任意元素
|
|
313
327
|
|
|
314
328
|
// 分组操作
|
|
315
|
-
const
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
const byAge = collectable.groupBy(
|
|
319
|
-
person => person.age,
|
|
320
|
-
person => person.name
|
|
329
|
+
const grouped = data.groupBy(
|
|
330
|
+
n => n > 5 ? "large" : "small",
|
|
331
|
+
n => n * 2
|
|
321
332
|
);
|
|
322
|
-
//
|
|
323
|
-
|
|
324
|
-
// 转换为集合
|
|
325
|
-
const array = collectable.toArray(); // 原始数组
|
|
326
|
-
const set = collectable.toSet(); // Set 集合
|
|
327
|
-
const map = collectable.toMap(
|
|
328
|
-
person => person.name,
|
|
329
|
-
person => person.age
|
|
330
|
-
); // Map { "Alice" => 25, "Bob" => 30, "Charlie" => 25 }
|
|
333
|
+
// {small: [4, 8], large: [12, 16, 20]}
|
|
331
334
|
|
|
332
335
|
// 归约操作
|
|
333
|
-
const
|
|
334
|
-
const oldest = collectable.reduce((a, b) => a.age > b.age ? a : b); // Optional.of({name: "Bob", age: 30, ...})
|
|
335
|
-
```
|
|
336
|
+
const sum = data.reduce(0, (acc, n) => acc + n); // 30
|
|
336
337
|
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
- **特点**:最快的收集器,不进行排序
|
|
341
|
-
- **使用场景**:顺序不重要,追求最大性能
|
|
342
|
-
- **方法**:继承 Collectable 的所有方法
|
|
343
|
-
|
|
344
|
-
#### OrderedCollectable<E>
|
|
345
|
-
- **特点**:保证元素有序,性能较低
|
|
346
|
-
- **使用场景**:需要排序结果的场景
|
|
347
|
-
- **特殊方法**:继承所有方法,内部维护排序状态
|
|
338
|
+
// 输出操作
|
|
339
|
+
data.join(", "); // "2, 4, 6, 8, 10"
|
|
340
|
+
```
|
|
348
341
|
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
342
|
+
## 统计分析方法
|
|
343
|
+
|
|
344
|
+
### NumericStatistics 方法
|
|
345
|
+
|
|
346
|
+
| 方法 | 描述 | 时间复杂度 | 空间复杂度 |
|
|
347
|
+
|------|------|------------|------------|
|
|
348
|
+
| `range()` | 极差 | O(n) | O(1) |
|
|
349
|
+
| `variance()` | 方差 | O(n) | O(1) |
|
|
350
|
+
| `standardDeviation()` | 标准差 | O(n) | O(1) |
|
|
351
|
+
| `mean()` | 平均值 | O(n) | O(1) |
|
|
352
|
+
| `median()` | 中位数 | O(n log n) | O(n) |
|
|
353
|
+
| `mode()` | 众数 | O(n) | O(n) |
|
|
354
|
+
| `frequency()` | 频率分布 | O(n) | O(n) |
|
|
355
|
+
| `summate()` | 求和 | O(n) | O(1) |
|
|
356
|
+
| `quantile(quantile)` | 分位数 | O(n log n) | O(n) |
|
|
357
|
+
| `interquartileRange()` | 四分位距 | O(n log n) | O(n) |
|
|
358
|
+
| `skewness()` | 偏度 | O(n) | O(1) |
|
|
359
|
+
| `kurtosis()` | 峰度 | O(n) | O(1) |
|
|
355
360
|
|
|
356
|
-
**代码示例补充:**
|
|
357
361
|
```typescript
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
//
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
const
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
const tumblingWindows = windowed.tumble(4n); // 翻滚窗口大小4
|
|
376
|
-
// 窗口1: [1, 2, 3, 4], 窗口2: [5, 6, 7, 8], ...
|
|
362
|
+
// 统计分析示例
|
|
363
|
+
const numbers = from([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
|
|
364
|
+
.toNumericStatistics();
|
|
365
|
+
|
|
366
|
+
console.log("平均值:", numbers.mean()); // 5.5
|
|
367
|
+
console.log("中位数:", numbers.median()); // 5.5
|
|
368
|
+
console.log("标准差:", numbers.standardDeviation()); // ~2.87
|
|
369
|
+
console.log("总和:", numbers.summate()); // 55
|
|
370
|
+
|
|
371
|
+
// 使用映射器的统计分析
|
|
372
|
+
const objects = from([
|
|
373
|
+
{ value: 10 },
|
|
374
|
+
{ value: 20 },
|
|
375
|
+
{ value: 30 }
|
|
376
|
+
]).toNumericStatistics();
|
|
377
|
+
|
|
378
|
+
console.log("映射平均值:", objects.mean(obj => obj.value)); // 20
|
|
377
379
|
```
|
|
378
380
|
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
#### 统计计算操作
|
|
384
|
-
|
|
385
|
-
| 方法 | 返回类型 | 描述 | 算法复杂度 |
|
|
386
|
-
|------|----------|------|------------|
|
|
387
|
-
| `maximum()` | `Optional<E>` | 最大值 | O(n) |
|
|
388
|
-
| `minimum()` | `Optional<E>` | 最小值 | O(n) |
|
|
389
|
-
| `range()` | `D` | 极差(最大值-最小值) | O(n) |
|
|
390
|
-
| `variance()` | `D` | 方差 | O(n) |
|
|
391
|
-
| `standardDeviation()` | `D` | 标准差 | O(n) |
|
|
392
|
-
| `mean()` | `D` | 平均值 | O(n) |
|
|
393
|
-
| `median()` | `D` | 中位数 | O(n log n) |
|
|
394
|
-
| `mode()` | `D` | 众数 | O(n) |
|
|
395
|
-
| `frequency()` | `Map<D, bigint>` | 频率分布 | O(n) |
|
|
396
|
-
| `summate()` | `D` | 求和 | O(n) |
|
|
397
|
-
| `quantile(quantile)` | `D` | 分位数 | O(n log n) |
|
|
398
|
-
| `interquartileRange()` | `D` | 四分位距 | O(n log n) |
|
|
399
|
-
| `skewness()` | `D` | 偏度 | O(n) |
|
|
400
|
-
| `kurtosis()` | `D` | 峰度 | O(n) |
|
|
401
|
-
|
|
402
|
-
**代码示例补充:**
|
|
381
|
+
## 性能选择指南
|
|
382
|
+
|
|
383
|
+
### 选择无序收集器(性能优先)
|
|
403
384
|
```typescript
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
//
|
|
409
|
-
const stats = numbers.toNumericStatistics();
|
|
410
|
-
|
|
411
|
-
// 基本统计
|
|
412
|
-
const count = stats.count(); // 10n
|
|
413
|
-
const max = stats.maximum(); // Optional.of(10)
|
|
414
|
-
const min = stats.minimum(); // Optional.of(1)
|
|
415
|
-
const range = stats.range(); // 9
|
|
416
|
-
const mean = stats.mean(); // 5.5
|
|
417
|
-
const median = stats.median(); // 5.5
|
|
418
|
-
const sum = stats.summate(); // 55
|
|
419
|
-
|
|
420
|
-
// 高级统计
|
|
421
|
-
const variance = stats.variance(); // 8.25
|
|
422
|
-
const stdDev = stats.standardDeviation(); // 2.872
|
|
423
|
-
const mode = stats.mode(); // 任何值(因为都出现一次)
|
|
424
|
-
const q1 = stats.quantile(0.25); // 3.25
|
|
425
|
-
const q3 = stats.quantile(0.75); // 7.75
|
|
426
|
-
const iqr = stats.interquartileRange(); // 4.5
|
|
427
|
-
|
|
428
|
-
// 频率分布
|
|
429
|
-
const freq = stats.frequency(); // Map {1 => 1n, 2 => 1n, ...}
|
|
385
|
+
// 当不需要顺序保证时,使用无序收集器获得最佳性能
|
|
386
|
+
const highPerformance = data
|
|
387
|
+
.filter(predicate)
|
|
388
|
+
.map(mapper)
|
|
389
|
+
.toUnoredered(); // 最佳性能
|
|
430
390
|
```
|
|
431
391
|
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
**NumericStatistics<E>**
|
|
435
|
-
- 处理 number 类型的统计分析
|
|
436
|
-
- 所有统计计算返回 number 类型
|
|
437
|
-
|
|
438
|
-
**BigIntStatistics<E>**
|
|
439
|
-
- 处理 bigint 类型的统计分析
|
|
440
|
-
- 所有统计计算返回 bigint 类型
|
|
441
|
-
|
|
442
|
-
**代码示例补充:**
|
|
392
|
+
### 选择有序收集器(需要顺序)
|
|
443
393
|
```typescript
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
const numberData = from([10, 20, 30, 40, 50]);
|
|
448
|
-
const numericStats = numberData.toNumericStatistics();
|
|
449
|
-
|
|
450
|
-
console.log(numericStats.mean()); // 30
|
|
451
|
-
console.log(numericStats.summate()); // 150
|
|
452
|
-
|
|
453
|
-
// 大整数统计
|
|
454
|
-
const bigintData = from([100n, 200n, 300n, 400n, 500n]);
|
|
455
|
-
const bigintStats = bigintData.toBigIntStatistics();
|
|
394
|
+
// 当需要保持元素顺序时,使用有序收集器
|
|
395
|
+
const ordered = data.sorted(comparator);
|
|
396
|
+
```
|
|
456
397
|
|
|
457
|
-
|
|
458
|
-
|
|
398
|
+
### 选择窗口收集器(窗口操作)
|
|
399
|
+
```typescript
|
|
400
|
+
// 需要进行窗口操作时
|
|
401
|
+
const windowed = data
|
|
402
|
+
.toWindow()
|
|
403
|
+
.slide(5n, 2n); // 滑动窗口
|
|
404
|
+
```
|
|
459
405
|
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
{ value: 45 }
|
|
466
|
-
]);
|
|
406
|
+
### 选择统计分析(数值计算)
|
|
407
|
+
```typescript
|
|
408
|
+
// 需要进行统计分析时
|
|
409
|
+
const stats = data
|
|
410
|
+
.toNumericStatistics(); // 数值统计
|
|
467
411
|
|
|
468
|
-
const
|
|
469
|
-
|
|
470
|
-
const sumWithMapper = objectStats.summate(obj => obj.value); // 120
|
|
412
|
+
const bigIntStats = data
|
|
413
|
+
.toBigintStatistics(); // 大数统计
|
|
471
414
|
```
|
|
472
415
|
|
|
473
|
-
|
|
416
|
+
[GitHub](https://github.com/eloyhere/semantic-typescript)
|
|
417
|
+
[NPMJS](https://www.npmjs.com/package/semantic-typescript)
|
|
474
418
|
|
|
475
|
-
|
|
476
|
-
import { from, validate, invalidate } from 'semantic-typescript';
|
|
477
|
-
|
|
478
|
-
// 1. 创建数据流
|
|
479
|
-
const rawData = [5, 2, 8, 1, null, 9, 3, undefined, 7, 4, 6];
|
|
480
|
-
const semanticStream = from(rawData);
|
|
481
|
-
|
|
482
|
-
// 2. 流处理管道
|
|
483
|
-
const processedStream = semanticStream
|
|
484
|
-
.filter(val => validate(val)) // 过滤掉 null 和 undefined
|
|
485
|
-
.map(val => val! * 2) // 每个值乘以2(使用 ! 因为 validate 确保了不为空)
|
|
486
|
-
.distinct(); // 去重
|
|
487
|
-
|
|
488
|
-
// 3. 转换为 Collectable 并使用终端操作
|
|
489
|
-
const collectable = processedStream.toUnordered();
|
|
490
|
-
|
|
491
|
-
// 4. 数据验证和使用
|
|
492
|
-
if (!collectable.isEmpty()) {
|
|
493
|
-
const results = collectable
|
|
494
|
-
.filter(x => x > 5) // 再次过滤
|
|
495
|
-
.toArray(); // 转换为数组
|
|
496
|
-
|
|
497
|
-
console.log("处理结果:", results); // [16, 18, 14, 8, 12]
|
|
498
|
-
|
|
499
|
-
// 统计信息
|
|
500
|
-
const stats = processedStream.toNumericStatistics();
|
|
501
|
-
console.log("平均值:", stats.mean()); // 11.2
|
|
502
|
-
console.log("总和:", stats.summate()); // 56
|
|
503
|
-
}
|
|
419
|
+
## 注意事项
|
|
504
420
|
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
console.log("有效数据:", validData); // [1, 3, 4]
|
|
511
|
-
console.log("无效数据:", invalidData); // [null, null]
|
|
512
|
-
```
|
|
421
|
+
1. **排序操作的影响**:在有序收集器中,`sorted()` 操作会覆盖 `redirect`、`translate`、`shuffle`、`reverse` 的效果
|
|
422
|
+
2. **性能考虑**:如果不需要顺序保证,优先使用 `toUnoredered()` 获得更好性能
|
|
423
|
+
3. **内存使用**:排序操作需要 O(n) 的额外空间
|
|
424
|
+
4. **实时数据**:Semantic 流适合处理实时数据,支持异步数据源
|
|
513
425
|
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
1. **创建流**:使用 `from()`, `range()`, `fill()` 等工厂方法创建 Semantic 实例
|
|
517
|
-
2. **流转换**:在 Semantic 实例上调用 `map()`, `filter()`, `distinct()` 等方法
|
|
518
|
-
3. **转换为 Collectable**:必须通过 Semantic 实例调用以下方法之一:
|
|
519
|
-
- `toOrdered()` - 有序收集器
|
|
520
|
-
- `toUnordered()` - 无序收集器(最快)
|
|
521
|
-
- `toWindow()` - 窗口收集器
|
|
522
|
-
- `toNumericStatistics()` - 数值统计
|
|
523
|
-
- `toBigIntStatistics()` - 大整数统计
|
|
524
|
-
- `sorted()` - 自然排序
|
|
525
|
-
- `sorted(comparator)` - 自定义排序
|
|
526
|
-
4. **终端操作**:在 Collectable 实例上调用 `toArray()`, `count()`, `summate()` 等终端方法
|
|
527
|
-
5. **数据验证**:使用 `validate()` 确保数据不为 null/undefined,使用 `invalidate()` 检查无效数据
|
|
528
|
-
|
|
529
|
-
这样的设计确保了类型安全性和性能优化,同时提供了丰富的流处理功能。
|
|
426
|
+
这个库为 TypeScript 开发者提供了强大而灵活的流式处理能力,结合了函数式编程的优点和类型安全的保障。
|