semantic-typescript 0.0.7 → 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 +360 -269
- package/readme.de.md +356 -264
- package/readme.es.md +357 -264
- package/readme.fr.md +357 -264
- package/readme.jp.md +362 -270
- package/readme.kr.md +361 -269
- package/readme.md +361 -270
- package/readme.ru.md +428 -0
- package/readme.tw.md +354 -263
package/readme.cn.md
CHANGED
|
@@ -1,335 +1,426 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Semantic-TypeScript 流处理库
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
提供可组合的函数式风格构造,用于处理集合、流和序列 —— 支持排序、过滤、分组、统计分析等功能。
|
|
3
|
+
## 简介
|
|
5
4
|
|
|
6
|
-
|
|
5
|
+
Semantic-TypeScript 是一个受到 JavaScript GeneratorFunction、Java Stream 和 MySQL Index 启发而设计的现代化流处理库。该库的核心设计理念是基于数据索引构建高效的数据处理管道,为前端开发提供类型安全、函数式风格的流式操作体验。
|
|
7
6
|
|
|
8
|
-
|
|
7
|
+
与传统的同步处理不同,Semantic 采用异步处理模式。在创建数据流时,终端接收数据的时间完全取决于上游何时调用 `accept` 和 `interrupt` 回调函数,这种设计使得库能够优雅地处理实时数据流、大型数据集和异步数据源。
|
|
9
8
|
|
|
10
|
-
##
|
|
11
|
-
|
|
12
|
-
- ✅ 全程**类型安全泛型**
|
|
13
|
-
- ✅ **函数式编程**风格(map、filter、reduce 等)
|
|
14
|
-
- ✅ **语义数据流**(`Semantic<E>`)支持惰性求值
|
|
15
|
-
- ✅ **收集器**用于将流转换为具体结构
|
|
16
|
-
- ✅ **有序与无序收集器** —— `toUnordered()` **不排序,最快**!其他收集器会排序
|
|
17
|
-
- ✅ **排序支持**通过 `sorted()`、`toOrdered()`、比较器
|
|
18
|
-
- ✅ **统计分析**(`Statistics`、`NumericStatistics`、`BigIntStatistics`)
|
|
19
|
-
- ✅ **Optional<T>** 单体模式,安全处理可空值
|
|
20
|
-
- ✅ 基于**迭代器与生成器**的设计 —— 适用于大型/异步数据
|
|
21
|
-
|
|
22
|
-
---
|
|
23
|
-
|
|
24
|
-
## 📦 安装
|
|
9
|
+
## 安装
|
|
25
10
|
|
|
26
11
|
```bash
|
|
27
12
|
npm install semantic-typescript
|
|
28
13
|
```
|
|
29
14
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
## 🧠 核心概念
|
|
33
|
-
|
|
34
|
-
### 1. `Optional<T>` – 安全的可空值处理
|
|
35
|
-
|
|
36
|
-
用于包装可能为 `null` 或 `undefined` 的值的单体制容器。
|
|
37
|
-
|
|
38
|
-
#### 方法:
|
|
39
|
-
|
|
40
|
-
| 方法 | 说明 | 示例 |
|
|
41
|
-
|------|------|------|
|
|
42
|
-
| `of(value)` | 包装值(可为空) | `Optional.of(null)` |
|
|
43
|
-
| `ofNullable(v)` | 包装,允许空值 | `Optional.ofNullable(someVar)` |
|
|
44
|
-
| `ofNonNull(v)` | 包装,若为 null/undefined 则抛出 | `Optional.ofNonNull(5)` |
|
|
45
|
-
| `get()` | 获取值,空则抛出 | `opt.get()` |
|
|
46
|
-
| `getOrDefault(d)` | 获取值或默认值 | `opt.getOrDefault(0)` |
|
|
47
|
-
| `ifPresent(fn)` | 若存在则执行副作用 | `opt.ifPresent(x => console.log(x))` |
|
|
48
|
-
| `map(fn)` | 若存在则转换值 | `opt.map(x => x + 1)` |
|
|
49
|
-
| `filter(fn)` | 仅保留满足谓词的值 | `opt.filter(x => x > 0)` |
|
|
50
|
-
| `isEmpty()` | 检查是否为空 | `opt.isEmpty()` |
|
|
51
|
-
| `isPresent()` | 检查是否有值 | `opt.isPresent()` |
|
|
15
|
+
## 基础类型
|
|
52
16
|
|
|
53
|
-
|
|
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>` | 生成器函数 |
|
|
54
46
|
|
|
55
47
|
```typescript
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
const
|
|
59
|
-
|
|
60
|
-
const opt = Optional.ofNullable(value);
|
|
61
|
-
|
|
62
|
-
const result = opt
|
|
63
|
-
.filter(v => v > 5)
|
|
64
|
-
.map(v => v * 2)
|
|
65
|
-
.getOrDefault(0);
|
|
66
|
-
|
|
67
|
-
console.log(result); // 20 或 0
|
|
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;
|
|
68
52
|
```
|
|
69
53
|
|
|
70
|
-
|
|
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) |
|
|
71
79
|
|
|
72
|
-
|
|
80
|
+
```typescript
|
|
81
|
+
// 类型守卫使用示例
|
|
82
|
+
const value: unknown = "hello";
|
|
73
83
|
|
|
74
|
-
|
|
84
|
+
if (isString(value)) {
|
|
85
|
+
console.log(value.length); // 类型安全,value 被推断为 string
|
|
86
|
+
}
|
|
75
87
|
|
|
76
|
-
|
|
88
|
+
if (isOptional(someValue)) {
|
|
89
|
+
someValue.ifPresent(val => console.log(val));
|
|
90
|
+
}
|
|
91
|
+
```
|
|
77
92
|
|
|
78
|
-
|
|
93
|
+
## 工具函数
|
|
79
94
|
|
|
80
|
-
| 函数 |
|
|
81
|
-
|
|
82
|
-
| `
|
|
83
|
-
| `
|
|
84
|
-
| `fill(element, count)` | 重复元素 N 次 | `fill('a', 3n)` |
|
|
85
|
-
| `iterate(gen)` | 使用自定义生成器函数 | `iterate(genFn)` |
|
|
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) |
|
|
86
99
|
|
|
87
|
-
|
|
100
|
+
```typescript
|
|
101
|
+
// 工具函数使用示例
|
|
102
|
+
const numbers = [3, 1, 4, 1, 5];
|
|
103
|
+
numbers.sort(useCompare); // [1, 1, 3, 4, 5]
|
|
88
104
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
| `filter(fn)` | 保留满足谓词的元素 | `.filter(x => x > 10)` |
|
|
93
|
-
| `limit(n)` | 限制前 N 个元素 | `.limit(5)` |
|
|
94
|
-
| `skip(n)` | 跳过前 N 个元素 | `.skip(2)` |
|
|
95
|
-
| `distinct()` | 去重(默认使用 Set) | `.distinct()` |
|
|
96
|
-
| `sorted()` | 排序元素(需自然排序) | `.sorted()` |
|
|
97
|
-
| `sorted(comparator)` | 自定义排序 | `.sorted((a,b) => a - b)` |
|
|
98
|
-
| `toOrdered()` | 排序并返回 OrderedCollectable | `.toOrdered()` |
|
|
99
|
-
| `toUnordered()` | **不排序** – 最快的收集器 | `.toUnordered()` ✅ |
|
|
100
|
-
| `collect(collector)` | 使用收集器聚合 | `.collect(Collector.full(...))` |
|
|
101
|
-
| `toArray()` | 转换为数组 | `.toArray()` |
|
|
102
|
-
| `toSet()` | 转换为 Set | `.toSet()` |
|
|
103
|
-
| `toMap(keyFn, valFn)` | 转换为 Map | `.toMap(x => x.id, x => x)` |
|
|
105
|
+
const randomNum = useRandom(42); // 基于种子的随机数
|
|
106
|
+
const randomBigInt = useRandom(1000n); // BigInt 随机数
|
|
107
|
+
```
|
|
104
108
|
|
|
105
|
-
|
|
109
|
+
## 工厂方法
|
|
106
110
|
|
|
107
|
-
###
|
|
111
|
+
### Optional 工厂方法
|
|
108
112
|
|
|
109
|
-
|
|
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) |
|
|
110
119
|
|
|
111
120
|
```typescript
|
|
112
|
-
|
|
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
|
|
113
129
|
```
|
|
114
130
|
|
|
115
|
-
|
|
116
|
-
当顺序无关紧要且您需要最大速度时,请使用此方法。
|
|
117
|
-
|
|
118
|
-
---
|
|
131
|
+
### Collector 工厂方法
|
|
119
132
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
133
|
+
| 方法 | 描述 | 时间复杂度 | 空间复杂度 |
|
|
134
|
+
|------|------|------------|------------|
|
|
135
|
+
| `Collector.full(identity, accumulator, finisher)` | 创建完整收集器 | O(1) | O(1) |
|
|
136
|
+
| `Collector.shortable(identity, interruptor, accumulator, finisher)` | 创建可中断收集器 | O(1) | O(1) |
|
|
123
137
|
|
|
124
138
|
```typescript
|
|
125
|
-
|
|
126
|
-
const
|
|
127
|
-
|
|
139
|
+
// Collector 使用示例
|
|
140
|
+
const sumCollector = Collector.full(
|
|
141
|
+
() => 0,
|
|
142
|
+
(sum, num) => sum + num,
|
|
143
|
+
result => result
|
|
144
|
+
);
|
|
145
|
+
|
|
146
|
+
const numbers = from([1, 2, 3, 4, 5]);
|
|
147
|
+
const total = numbers.toUnoredered().collect(sumCollector); // 15
|
|
128
148
|
```
|
|
129
149
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
---
|
|
150
|
+
### Semantic 工厂方法
|
|
133
151
|
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
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) |
|
|
139
162
|
|
|
140
163
|
```typescript
|
|
141
|
-
|
|
142
|
-
|
|
164
|
+
// Semantic 工厂方法使用示例
|
|
165
|
+
|
|
166
|
+
// 从 Blob 创建流(分块读取)
|
|
167
|
+
blob(someBlob, 1024n)
|
|
168
|
+
.toUnordered()
|
|
169
|
+
.write(WritableStream)
|
|
170
|
+
.then(callback) // 写入流成功
|
|
171
|
+
.catch(writeFi); // 写入流失败
|
|
172
|
+
|
|
173
|
+
// 创建空流,在拼接其它流之前不会执行
|
|
174
|
+
empty<string>()
|
|
175
|
+
.toUnordered()
|
|
176
|
+
.join(); //[]
|
|
177
|
+
|
|
178
|
+
// 创建填充流
|
|
179
|
+
const filledStream = fill("hello", 3); // "hello", "hello", "hello"
|
|
180
|
+
|
|
181
|
+
// 创建初始延迟2秒、执行周期5秒的时序流,基于计时器机制实现,因系统调度精度限制可能存在时间漂移。
|
|
182
|
+
const intervalStream = interval(5000, 2000);
|
|
183
|
+
|
|
184
|
+
// 从可迭代对象创建流
|
|
185
|
+
const numberStream = from([1, 2, 3, 4, 5]);
|
|
186
|
+
const stringStream = from(new Set(["Alex", "Bob"]));
|
|
187
|
+
|
|
188
|
+
// 创建范围流
|
|
189
|
+
const rangeStream = range(1, 10, 2); // 1, 3, 5, 7, 9
|
|
190
|
+
|
|
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)); //接收消息
|
|
143
197
|
```
|
|
144
198
|
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
|
161
|
-
|
|
162
|
-
| `
|
|
163
|
-
| `
|
|
164
|
-
| `
|
|
165
|
-
| `
|
|
166
|
-
| `
|
|
167
|
-
| `
|
|
168
|
-
| `
|
|
169
|
-
| `
|
|
170
|
-
|
|
171
|
-
---
|
|
172
|
-
|
|
173
|
-
### 7. `OrderedCollectable<E>` – 排序数据
|
|
174
|
-
|
|
175
|
-
如果您希望元素**自动排序**,请使用此类。
|
|
176
|
-
|
|
177
|
-
可接受**自定义比较器**或使用自然排序。
|
|
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) |
|
|
178
224
|
|
|
179
225
|
```typescript
|
|
180
|
-
|
|
181
|
-
const
|
|
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(); // 转换为数组
|
|
182
243
|
```
|
|
183
244
|
|
|
184
|
-
|
|
245
|
+
## 收集器转换方法
|
|
185
246
|
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
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) |
|
|
191
255
|
|
|
192
256
|
```typescript
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
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
|
+
});
|
|
196
286
|
```
|
|
197
287
|
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
|
215
|
-
|
|
216
|
-
| `
|
|
217
|
-
| `
|
|
218
|
-
| `
|
|
219
|
-
| `
|
|
220
|
-
| `
|
|
221
|
-
| `
|
|
222
|
-
| `
|
|
223
|
-
| `standardDeviation()` | 标准差 | `.standardDeviation()` |
|
|
224
|
-
| `summate()` | 元素总和 | `.summate()` |
|
|
225
|
-
| `quantile(q)` | 第 q 分位数(0–1) | `.quantile(0.5)` → 中位数 |
|
|
226
|
-
| `frequency()` | 频率映射表 | `.frequency()` |
|
|
227
|
-
|
|
228
|
-
---
|
|
229
|
-
|
|
230
|
-
## 🧪 完整示例
|
|
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) |
|
|
231
313
|
|
|
232
314
|
```typescript
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
//
|
|
239
|
-
|
|
240
|
-
console.log(
|
|
241
|
-
|
|
242
|
-
//
|
|
243
|
-
|
|
244
|
-
console.log(
|
|
245
|
-
|
|
246
|
-
//
|
|
247
|
-
const
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
315
|
+
// Collectable 操作示例
|
|
316
|
+
const data = from([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
|
|
317
|
+
.filter(n => n % 2 === 0)
|
|
318
|
+
.toOrdered();
|
|
319
|
+
|
|
320
|
+
// 匹配检查
|
|
321
|
+
console.log(data.anyMatch(n => n > 5)); // true
|
|
322
|
+
console.log(data.allMatch(n => n < 20)); // true
|
|
323
|
+
|
|
324
|
+
// 查找操作
|
|
325
|
+
data.findFirst().ifPresent(n => console.log(n)); // 2
|
|
326
|
+
data.findAny().ifPresent(n => console.log(n)); // 任意元素
|
|
327
|
+
|
|
328
|
+
// 分组操作
|
|
329
|
+
const grouped = data.groupBy(
|
|
330
|
+
n => n > 5 ? "large" : "small",
|
|
331
|
+
n => n * 2
|
|
332
|
+
);
|
|
333
|
+
// {small: [4, 8], large: [12, 16, 20]}
|
|
334
|
+
|
|
335
|
+
// 归约操作
|
|
336
|
+
const sum = data.reduce(0, (acc, n) => acc + n); // 30
|
|
337
|
+
|
|
338
|
+
// 输出操作
|
|
339
|
+
data.join(", "); // "2, 4, 6, 8, 10"
|
|
253
340
|
```
|
|
254
341
|
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
|
262
|
-
|
|
263
|
-
| `
|
|
264
|
-
| `
|
|
265
|
-
| `
|
|
266
|
-
| `
|
|
267
|
-
| `
|
|
268
|
-
| `
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
您可以创建自定义**生成器**用于无限或受控数据流:
|
|
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) |
|
|
275
360
|
|
|
276
361
|
```typescript
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
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
|
|
285
379
|
```
|
|
286
380
|
|
|
287
|
-
|
|
381
|
+
## 性能选择指南
|
|
288
382
|
|
|
383
|
+
### 选择无序收集器(性能优先)
|
|
289
384
|
```typescript
|
|
290
|
-
|
|
385
|
+
// 当不需要顺序保证时,使用无序收集器获得最佳性能
|
|
386
|
+
const highPerformance = data
|
|
387
|
+
.filter(predicate)
|
|
388
|
+
.map(mapper)
|
|
389
|
+
.toUnoredered(); // 最佳性能
|
|
291
390
|
```
|
|
292
391
|
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
---
|
|
300
|
-
|
|
301
|
-
## 🙌 贡献
|
|
302
|
-
|
|
303
|
-
欢迎提交 Pull Request、提出问题与想法!
|
|
304
|
-
|
|
305
|
-
---
|
|
306
|
-
|
|
307
|
-
## 🚀 快速开始总结
|
|
308
|
-
|
|
309
|
-
| 任务 | 方法 |
|
|
310
|
-
|------|------|
|
|
311
|
-
| 安全处理空值 | `Optional<T>` |
|
|
312
|
-
| 创建流 | `from([...])`、`range()`、`fill()` |
|
|
313
|
-
| 转换数据 | `map()`、`filter()` |
|
|
314
|
-
| 排序数据 | `sorted()`、`toOrdered()` |
|
|
315
|
-
| 不排序(最快 | `toUnordered()` ✅ |
|
|
316
|
-
| 分组/聚合 | `toMap()`、`group()`、`Collector` |
|
|
317
|
-
| 统计 | `NumericStatistics`、`mean()`、`median()` 等 |
|
|
392
|
+
### 选择有序收集器(需要顺序)
|
|
393
|
+
```typescript
|
|
394
|
+
// 当需要保持元素顺序时,使用有序收集器
|
|
395
|
+
const ordered = data.sorted(comparator);
|
|
396
|
+
```
|
|
318
397
|
|
|
319
|
-
|
|
398
|
+
### 选择窗口收集器(窗口操作)
|
|
399
|
+
```typescript
|
|
400
|
+
// 需要进行窗口操作时
|
|
401
|
+
const windowed = data
|
|
402
|
+
.toWindow()
|
|
403
|
+
.slide(5n, 2n); // 滑动窗口
|
|
404
|
+
```
|
|
320
405
|
|
|
321
|
-
|
|
406
|
+
### 选择统计分析(数值计算)
|
|
407
|
+
```typescript
|
|
408
|
+
// 需要进行统计分析时
|
|
409
|
+
const stats = data
|
|
410
|
+
.toNumericStatistics(); // 数值统计
|
|
322
411
|
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
412
|
+
const bigIntStats = data
|
|
413
|
+
.toBigintStatistics(); // 大数统计
|
|
414
|
+
```
|
|
326
415
|
|
|
327
|
-
|
|
416
|
+
[GitHub](https://github.com/eloyhere/semantic-typescript)
|
|
417
|
+
[NPMJS](https://www.npmjs.com/package/semantic-typescript)
|
|
328
418
|
|
|
329
|
-
|
|
419
|
+
## 注意事项
|
|
330
420
|
|
|
331
|
-
|
|
421
|
+
1. **排序操作的影响**:在有序收集器中,`sorted()` 操作会覆盖 `redirect`、`translate`、`shuffle`、`reverse` 的效果
|
|
422
|
+
2. **性能考虑**:如果不需要顺序保证,优先使用 `toUnoredered()` 获得更好性能
|
|
423
|
+
3. **内存使用**:排序操作需要 O(n) 的额外空间
|
|
424
|
+
4. **实时数据**:Semantic 流适合处理实时数据,支持异步数据源
|
|
332
425
|
|
|
333
|
-
|
|
334
|
-
- `toUnordered()` → **不排序,最快**
|
|
335
|
-
- 其他方法(如 `sorted()`、`toOrdered()`)→ **会排序数据**
|
|
426
|
+
这个库为 TypeScript 开发者提供了强大而灵活的流式处理能力,结合了函数式编程的优点和类型安全的保障。
|