semantic-typescript 0.0.7 → 0.0.8
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/package.json +1 -1
- package/readme.cn.md +441 -247
- package/readme.de.md +434 -240
- package/readme.es.md +434 -240
- package/readme.fr.md +434 -240
- package/readme.jp.md +434 -240
- package/readme.kr.md +441 -247
- package/readme.md +434 -240
- package/readme.ru.md +529 -0
- package/readme.tw.md +441 -247
package/readme.cn.md
CHANGED
|
@@ -1,335 +1,529 @@
|
|
|
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
|
-
##
|
|
9
|
+
## 核心特性
|
|
11
10
|
|
|
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
|
-
## 📦 安装
|
|
25
|
-
|
|
26
|
-
```bash
|
|
27
|
-
npm install semantic-typescript
|
|
28
|
-
```
|
|
29
|
-
|
|
30
|
-
---
|
|
31
|
-
|
|
32
|
-
## 🧠 核心概念
|
|
33
|
-
|
|
34
|
-
### 1. `Optional<T>` – 安全的可空值处理
|
|
35
|
-
|
|
36
|
-
用于包装可能为 `null` 或 `undefined` 的值的单体制容器。
|
|
37
|
-
|
|
38
|
-
#### 方法:
|
|
39
|
-
|
|
40
|
-
| 方法 | 说明 | 示例 |
|
|
11
|
+
| 特性 | 描述 | 优势 |
|
|
41
12
|
|------|------|------|
|
|
42
|
-
|
|
|
43
|
-
|
|
|
44
|
-
|
|
|
45
|
-
|
|
|
46
|
-
|
|
|
47
|
-
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
13
|
+
| **类型安全泛型** | 完整的 TypeScript 类型支持 | 编译时错误检测,更好的开发体验 |
|
|
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
|
+
### 流创建工厂
|
|
38
|
+
|
|
39
|
+
| 方法 | 签名 | 描述 | 示例 |
|
|
40
|
+
|------|------|------|------|
|
|
41
|
+
| `blob` | `(blob: Blob, chunk?: bigint) => Semantic<Uint8Array>` | 将 Blob 转换为字节流 | `blob(fileBlob, 1024n)` |
|
|
42
|
+
| `empty` | `<E>() => Semantic<E>` | 创建空流 | `empty<number>()` |
|
|
43
|
+
| `fill` | `<E>(element: E, count: bigint) => Semantic<E>` | 填充指定数量的元素 | `fill("hello", 5n)` |
|
|
44
|
+
| `from` | `<E>(iterable: Iterable<E>) => Semantic<E>` | 从可迭代对象创建流 | `from([1, 2, 3])` |
|
|
45
|
+
| `range` | `<N extends number\|bigint>(start: N, end: N, step?: N) => Semantic<N>` | 创建数值范围流 | `range(1, 10, 2)` |
|
|
46
|
+
| `iterate` | `<E>(generator: Generator<E>) => Semantic<E>` | 从生成器函数创建流 | `iterate(myGenerator)` |
|
|
47
|
+
| `websocket` | `(websocket: WebSocket) => Semantic<MessageEvent>` | 从 WebSocket 创建事件流 | `websocket(socket)` |
|
|
48
|
+
|
|
49
|
+
**代码示例补充:**
|
|
55
50
|
```typescript
|
|
56
|
-
import {
|
|
51
|
+
import { from, range, fill, empty } from 'semantic-typescript';
|
|
57
52
|
|
|
58
|
-
|
|
53
|
+
// 从数组创建流
|
|
54
|
+
const numberStream = from([1, 2, 3, 4, 5]);
|
|
59
55
|
|
|
60
|
-
|
|
56
|
+
// 创建数值范围流
|
|
57
|
+
const rangeStream = range(1, 10, 2); // 1, 3, 5, 7, 9
|
|
61
58
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
.map(v => v * 2)
|
|
65
|
-
.getOrDefault(0);
|
|
59
|
+
// 填充重复元素
|
|
60
|
+
const filledStream = fill("hello", 3n); // "hello", "hello", "hello"
|
|
66
61
|
|
|
67
|
-
|
|
62
|
+
// 创建空流
|
|
63
|
+
const emptyStream = empty<number>();
|
|
68
64
|
```
|
|
69
65
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
### 2. `Semantic<E>` – 惰性数据流
|
|
73
|
-
|
|
74
|
-
一个**惰性、可组合的序列**元素。类似于 Java Streams 或 Kotlin Sequences 的函数式流。
|
|
66
|
+
### 工具函数工厂
|
|
75
67
|
|
|
76
|
-
|
|
68
|
+
| 方法 | 签名 | 描述 | 示例 |
|
|
69
|
+
|------|------|------|------|
|
|
70
|
+
| `validate` | `<T>(t: MaybeInvalid<T>) => t is T` | 验证值是否有效 | `validate(null)` → `false` |
|
|
71
|
+
| `invalidate` | `<T>(t: MaybeInvalid<T>) => t is null\|undefined` | 验证值是否无效 | `invalidate(0)` → `false` |
|
|
72
|
+
| `useCompare` | `<T>(t1: T, t2: T) => number` | 通用比较函数 | `useCompare("a", "b")` → `-1` |
|
|
73
|
+
| `useRandom` | `<T = number\|bigint>(index: T) => T` | 伪随机数生成器 | `useRandom(5)` → 随机数 |
|
|
77
74
|
|
|
78
|
-
|
|
75
|
+
**代码示例补充:**
|
|
76
|
+
```typescript
|
|
77
|
+
import { validate, invalidate, useCompare, useRandom } from 'semantic-typescript';
|
|
79
78
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
| `iterate(gen)` | 使用自定义生成器函数 | `iterate(genFn)` |
|
|
79
|
+
// 验证数据有效性
|
|
80
|
+
const data: string | null = "hello";
|
|
81
|
+
if (validate(data)) {
|
|
82
|
+
console.log(data.toUpperCase()); // 安全调用,因为 validate 确保了 data 不为 null
|
|
83
|
+
}
|
|
86
84
|
|
|
87
|
-
|
|
85
|
+
const nullData: string | null = null;
|
|
86
|
+
if (invalidate(nullData)) {
|
|
87
|
+
console.log("数据无效"); // 会执行,因为 invalidate 检测到 null
|
|
88
|
+
}
|
|
88
89
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
| `map(fn)` | 转换每个元素 | `.map(x => x * 2)` |
|
|
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)` |
|
|
104
|
-
|
|
105
|
-
---
|
|
106
|
-
|
|
107
|
-
### 3. `toUnordered()` – 🚀 最快,不排序
|
|
108
|
-
|
|
109
|
-
如果您**不关心顺序**且希望获得**最佳性能**,请使用:
|
|
90
|
+
// 比较值
|
|
91
|
+
const comparison = useCompare("apple", "banana"); // -1
|
|
110
92
|
|
|
111
|
-
|
|
112
|
-
const
|
|
93
|
+
// 生成随机数
|
|
94
|
+
const randomNum = useRandom(42); // 基于种子 42 的随机数
|
|
113
95
|
```
|
|
114
96
|
|
|
115
|
-
|
|
116
|
-
当顺序无关紧要且您需要最大速度时,请使用此方法。
|
|
97
|
+
## 核心类详解
|
|
117
98
|
|
|
118
|
-
|
|
99
|
+
### Optional<T> - 安全空值处理
|
|
119
100
|
|
|
120
|
-
|
|
101
|
+
Optional 类提供了一种安全处理可能为 null 或 undefined 值的函数式方法。
|
|
121
102
|
|
|
122
|
-
|
|
103
|
+
| 方法 | 返回类型 | 描述 | 时间复杂度 |
|
|
104
|
+
|------|----------|------|------------|
|
|
105
|
+
| `filter(predicate: Predicate<T>)` | `Optional<T>` | 过滤满足条件的值 | O(1) |
|
|
106
|
+
| `get()` | `T` | 获取值,空则抛出错误 | O(1) |
|
|
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) |
|
|
123
115
|
|
|
116
|
+
**代码示例补充:**
|
|
124
117
|
```typescript
|
|
125
|
-
|
|
126
|
-
const customSorted = semanticStream.sorted((a, b) => a - b); // 自定义比较器
|
|
127
|
-
const orderedCollectable = semanticStream.toOrdered(); // 同样排序
|
|
128
|
-
```
|
|
118
|
+
import { Optional } from 'semantic-typescript';
|
|
129
119
|
|
|
130
|
-
|
|
120
|
+
// 创建 Optional 实例
|
|
121
|
+
const optionalValue = Optional.ofNullable<string>(Math.random() > 0.5 ? "hello" : null);
|
|
131
122
|
|
|
132
|
-
|
|
123
|
+
// 链式操作
|
|
124
|
+
const result = optionalValue
|
|
125
|
+
.filter(val => val.length > 3) // 过滤长度大于3的值
|
|
126
|
+
.map(val => val.toUpperCase()) // 转换为大写
|
|
127
|
+
.getOrDefault("default"); // 获取值或默认值
|
|
133
128
|
|
|
134
|
-
|
|
129
|
+
console.log(result); // "HELLO" 或 "default"
|
|
135
130
|
|
|
136
|
-
|
|
131
|
+
// 安全操作
|
|
132
|
+
optionalValue.ifPresent(val => {
|
|
133
|
+
console.log(`值存在: ${val}`);
|
|
134
|
+
});
|
|
137
135
|
|
|
138
|
-
|
|
136
|
+
// 检查状态
|
|
137
|
+
if (optionalValue.isPresent()) {
|
|
138
|
+
console.log("有值");
|
|
139
|
+
} else if (optionalValue.isEmpty()) {
|
|
140
|
+
console.log("为空");
|
|
141
|
+
}
|
|
142
|
+
```
|
|
139
143
|
|
|
144
|
+
### Semantic<E> - 惰性数据流
|
|
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
|
+
**代码示例补充:**
|
|
140
173
|
```typescript
|
|
141
|
-
|
|
142
|
-
Collector.shortable(identity, interruptor, accumulator, finisher)
|
|
143
|
-
```
|
|
174
|
+
import { from } from 'semantic-typescript';
|
|
144
175
|
|
|
145
|
-
|
|
176
|
+
const stream = from([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
|
|
146
177
|
|
|
147
|
-
|
|
178
|
+
// 流转换操作示例
|
|
179
|
+
const processedStream = stream
|
|
180
|
+
.filter(x => x % 2 === 0) // 过滤偶数
|
|
181
|
+
.map(x => x * 2) // 每个元素乘以2
|
|
182
|
+
.distinct() // 去重
|
|
183
|
+
.limit(3) // 限制前3个元素
|
|
184
|
+
.peek((val, index) => console.log(`元素 ${val} 在索引 ${index}`)); // 查看元素
|
|
148
185
|
|
|
149
|
-
|
|
186
|
+
// 注意:此时流还未执行,需要转换为 Collectable 才能使用终端操作
|
|
187
|
+
```
|
|
150
188
|
|
|
151
|
-
|
|
189
|
+
#### 流终止操作
|
|
152
190
|
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
191
|
+
| 方法 | 返回类型 | 描述 | 性能特点 |
|
|
192
|
+
|------|----------|------|----------|
|
|
193
|
+
| `toOrdered()` | `OrderedCollectable<E>` | 转换为有序集合 | 排序操作,性能较低 |
|
|
194
|
+
| `toUnordered()` | `UnorderedCollectable<E>` | 转换为无序集合 | 最快,不排序 |
|
|
195
|
+
| `toWindow()` | `WindowCollectable<E>` | 转换为窗口集合 | 排序操作,性能较低 |
|
|
196
|
+
| `toNumericStatistics()` | `Statistics<E, number>` | 数值统计分析 | 排序操作,性能较低 |
|
|
197
|
+
| `toBigintStatistics()` | `Statistics<E, bigint>` | 大整数统计分析 | 排序操作,性能较低 |
|
|
198
|
+
| `sorted()` | `OrderedCollectable<E>` | 自然排序 | 覆盖重定向结果 |
|
|
199
|
+
| `sorted(comparator)` | `OrderedCollectable<E>` | 自定义排序 | 覆盖重定向结果 |
|
|
157
200
|
|
|
158
|
-
|
|
201
|
+
**代码示例补充:**
|
|
202
|
+
```typescript
|
|
203
|
+
import { from } from 'semantic-typescript';
|
|
159
204
|
|
|
160
|
-
|
|
161
|
-
|------|------|------|
|
|
162
|
-
| `count()` | 计数元素 | `.count()` |
|
|
163
|
-
| `toArray()` | 转为数组 | `.toArray()` |
|
|
164
|
-
| `toSet()` | 转为 Set | `.toSet()` |
|
|
165
|
-
| `toMap(k, v)` | 转为 Map | `.toMap(x => x.id, x => x)` |
|
|
166
|
-
| `group(k)` | 按键分组 | `.group(x => x.category)` |
|
|
167
|
-
| `findAny()` | 任意匹配元素(Optional) | `.findAny()` |
|
|
168
|
-
| `findFirst()` | 第一个元素(Optional) | `.findFirst()` |
|
|
169
|
-
| `reduce(...)` | 自定义缩减 | `.reduce((a,b) => a + b, 0)` |
|
|
205
|
+
const semanticStream = from([5, 2, 8, 1, 9, 3, 7, 4, 6]);
|
|
170
206
|
|
|
171
|
-
|
|
207
|
+
// 转换为有序集合(性能较低)
|
|
208
|
+
const ordered = semanticStream.toOrdered();
|
|
172
209
|
|
|
173
|
-
|
|
210
|
+
// 转换为无序集合(最快)
|
|
211
|
+
const unordered = semanticStream.toUnordered();
|
|
174
212
|
|
|
175
|
-
|
|
213
|
+
// 自然排序
|
|
214
|
+
const sortedNatural = semanticStream.sorted();
|
|
176
215
|
|
|
177
|
-
|
|
216
|
+
// 自定义排序
|
|
217
|
+
const sortedCustom = semanticStream.sorted((a, b) => b - a); // 降序排序
|
|
178
218
|
|
|
179
|
-
|
|
180
|
-
const
|
|
181
|
-
const customSorted = new OrderedCollectable(stream, (a, b) => b - a);
|
|
182
|
-
```
|
|
219
|
+
// 转换为统计对象
|
|
220
|
+
const stats = semanticStream.toNumericStatistics();
|
|
183
221
|
|
|
184
|
-
|
|
222
|
+
// 注意:必须通过 Semantic 实例调用上述方法得到 Collectable 后才能使用终端方法
|
|
223
|
+
```
|
|
185
224
|
|
|
186
|
-
|
|
225
|
+
### Collector<E, A, R> - 数据收集器
|
|
187
226
|
|
|
188
|
-
|
|
227
|
+
收集器用于将流数据聚合为特定结构。
|
|
189
228
|
|
|
190
|
-
|
|
229
|
+
| 方法 | 描述 | 使用场景 |
|
|
230
|
+
|------|------|----------|
|
|
231
|
+
| `collect(generator)` | 执行数据收集 | 流终止操作 |
|
|
232
|
+
| `static full(identity, accumulator, finisher)` | 创建完整收集器 | 需要完整处理 |
|
|
233
|
+
| `static shortable(identity, interruptor, accumulator, finisher)` | 创建可中断收集器 | 可能提前终止 |
|
|
191
234
|
|
|
235
|
+
**代码示例补充:**
|
|
192
236
|
```typescript
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
237
|
+
import { Collector } from 'semantic-typescript';
|
|
238
|
+
|
|
239
|
+
// 创建自定义收集器
|
|
240
|
+
const sumCollector = Collector.full(
|
|
241
|
+
() => 0, // 初始值
|
|
242
|
+
(acc, value) => acc + value, // 累加器
|
|
243
|
+
result => result // 完成函数
|
|
244
|
+
);
|
|
245
|
+
|
|
246
|
+
// 使用收集器(需要先通过 Semantic 转换为 Collectable)
|
|
247
|
+
const numbers = from([1, 2, 3, 4, 5]);
|
|
248
|
+
const sum = numbers.toUnordered().collect(sumCollector); // 15
|
|
196
249
|
```
|
|
197
250
|
|
|
198
|
-
|
|
199
|
-
✅ **顺序无关紧要时的最佳性能**
|
|
251
|
+
### Collectable<E> - 可收集数据抽象类
|
|
200
252
|
|
|
201
|
-
|
|
253
|
+
提供丰富的数据聚合和转换方法。**注意:必须先通过 Semantic 实例调用 sorted(), toOrdered() 等方法得到 Collectable 实例后才能使用以下方法。**
|
|
202
254
|
|
|
203
|
-
|
|
255
|
+
#### 数据查询操作
|
|
204
256
|
|
|
205
|
-
|
|
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()` |
|
|
206
266
|
|
|
207
|
-
|
|
267
|
+
**代码示例补充:**
|
|
268
|
+
```typescript
|
|
269
|
+
import { from } from 'semantic-typescript';
|
|
208
270
|
|
|
209
|
-
|
|
210
|
-
- `BigIntStatistics<E>` – 适用于 `bigint` 值
|
|
271
|
+
const numbers = from([1, 2, 3, 4, 5]);
|
|
211
272
|
|
|
212
|
-
|
|
273
|
+
// 必须先转换为 Collectable 才能使用终端方法
|
|
274
|
+
const collectable = numbers.toUnordered();
|
|
213
275
|
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
| `variance()` | 方差 | `.variance()` |
|
|
223
|
-
| `standardDeviation()` | 标准差 | `.standardDeviation()` |
|
|
224
|
-
| `summate()` | 元素总和 | `.summate()` |
|
|
225
|
-
| `quantile(q)` | 第 q 分位数(0–1) | `.quantile(0.5)` → 中位数 |
|
|
226
|
-
| `frequency()` | 频率映射表 | `.frequency()` |
|
|
227
|
-
|
|
228
|
-
---
|
|
229
|
-
|
|
230
|
-
## 🧪 完整示例
|
|
276
|
+
// 数据查询操作
|
|
277
|
+
const hasEven = collectable.anyMatch(x => x % 2 === 0); // true
|
|
278
|
+
const allPositive = collectable.allMatch(x => x > 0); // true
|
|
279
|
+
const count = collectable.count(); // 5n
|
|
280
|
+
const isEmpty = collectable.isEmpty(); // false
|
|
281
|
+
const firstElement = collectable.findFirst(); // Optional.of(1)
|
|
282
|
+
const anyElement = collectable.findAny(); // 任意元素
|
|
283
|
+
```
|
|
231
284
|
|
|
285
|
+
#### 数据聚合操作
|
|
286
|
+
|
|
287
|
+
| 方法 | 返回类型 | 描述 | 复杂度 |
|
|
288
|
+
|------|----------|------|--------|
|
|
289
|
+
| `group(classifier)` | `Map<K, E[]>` | 按分类器分组 | O(n) |
|
|
290
|
+
| `groupBy(keyExtractor, valueExtractor)` | `Map<K, V[]>` | 按键值提取器分组 | O(n) |
|
|
291
|
+
| `join()` | `string` | 连接为字符串 | O(n) |
|
|
292
|
+
| `join(delimiter)` | `string` | 带分隔符连接 | O(n) |
|
|
293
|
+
| `partition(count)` | `E[][]` | 按数量分区 | O(n) |
|
|
294
|
+
| `partitionBy(classifier)` | `E[][]` | 按分类器分区 | O(n) |
|
|
295
|
+
| `reduce(accumulator)` | `Optional<E>` | 归约操作 | O(n) |
|
|
296
|
+
| `reduce(identity, accumulator)` | `E` | 带初始值归约 | O(n) |
|
|
297
|
+
| `toArray()` | `E[]` | 转换为数组 | O(n) |
|
|
298
|
+
| `toMap(keyExtractor, valueExtractor)` | `Map<K, V>` | 转换为Map | O(n) |
|
|
299
|
+
| `toSet()` | `Set<E>` | 转换为Set | O(n) |
|
|
300
|
+
|
|
301
|
+
**代码示例补充:**
|
|
232
302
|
```typescript
|
|
233
|
-
import { from
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
//
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
303
|
+
import { from } from 'semantic-typescript';
|
|
304
|
+
|
|
305
|
+
const people = from([
|
|
306
|
+
{ name: "Alice", age: 25, city: "New York" },
|
|
307
|
+
{ name: "Bob", age: 30, city: "London" },
|
|
308
|
+
{ name: "Charlie", age: 25, city: "New York" }
|
|
309
|
+
]);
|
|
310
|
+
|
|
311
|
+
// 转换为 Collectable 后才能使用聚合操作
|
|
312
|
+
const collectable = people.toUnordered();
|
|
313
|
+
|
|
314
|
+
// 分组操作
|
|
315
|
+
const byCity = collectable.group(person => person.city);
|
|
316
|
+
// Map { "New York" => [{name: "Alice", ...}, {name: "Charlie", ...}], "London" => [{name: "Bob", ...}] }
|
|
317
|
+
|
|
318
|
+
const byAge = collectable.groupBy(
|
|
319
|
+
person => person.age,
|
|
320
|
+
person => person.name
|
|
321
|
+
);
|
|
322
|
+
// Map { 25 => ["Alice", "Charlie"], 30 => ["Bob"] }
|
|
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 }
|
|
331
|
+
|
|
332
|
+
// 归约操作
|
|
333
|
+
const totalAge = collectable.reduce(0, (acc, person) => acc + person.age); // 80
|
|
334
|
+
const oldest = collectable.reduce((a, b) => a.age > b.age ? a : b); // Optional.of({name: "Bob", age: 30, ...})
|
|
253
335
|
```
|
|
254
336
|
|
|
255
|
-
|
|
337
|
+
### 具体收集器实现
|
|
256
338
|
|
|
257
|
-
|
|
339
|
+
#### UnorderedCollectable<E>
|
|
340
|
+
- **特点**:最快的收集器,不进行排序
|
|
341
|
+
- **使用场景**:顺序不重要,追求最大性能
|
|
342
|
+
- **方法**:继承 Collectable 的所有方法
|
|
258
343
|
|
|
259
|
-
|
|
344
|
+
#### OrderedCollectable<E>
|
|
345
|
+
- **特点**:保证元素有序,性能较低
|
|
346
|
+
- **使用场景**:需要排序结果的场景
|
|
347
|
+
- **特殊方法**:继承所有方法,内部维护排序状态
|
|
260
348
|
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
| `useCompare(a, b)` | 通用比较函数 |
|
|
268
|
-
| `useRandom(x)` | 伪随机数生成器(有趣) |
|
|
349
|
+
#### WindowCollectable<E>
|
|
350
|
+
- **特点**:支持滑动窗口操作
|
|
351
|
+
- **使用场景**:时间序列数据分析
|
|
352
|
+
- **特有方法**:
|
|
353
|
+
- `slide(size, step)` - 滑动窗口
|
|
354
|
+
- `tumble(size)` - 翻滚窗口
|
|
269
355
|
|
|
270
|
-
|
|
356
|
+
**代码示例补充:**
|
|
357
|
+
```typescript
|
|
358
|
+
import { from } from 'semantic-typescript';
|
|
271
359
|
|
|
272
|
-
|
|
360
|
+
const data = from([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
|
|
273
361
|
|
|
274
|
-
|
|
362
|
+
// 无序收集器(最快)
|
|
363
|
+
const unordered = data.toUnordered();
|
|
364
|
+
const unorderedArray = unordered.toArray(); // 可能保持原顺序 [1, 2, 3, ...]
|
|
275
365
|
|
|
276
|
-
|
|
277
|
-
const
|
|
278
|
-
|
|
279
|
-
accept(i, BigInt(i));
|
|
280
|
-
if (i === 5) interrupt(i);
|
|
281
|
-
}
|
|
282
|
-
};
|
|
283
|
-
|
|
284
|
-
const s = new Semantic(gen);
|
|
285
|
-
```
|
|
366
|
+
// 有序收集器
|
|
367
|
+
const ordered = data.toOrdered();
|
|
368
|
+
const orderedArray = ordered.toArray(); // 保证排序 [1, 2, 3, ...]
|
|
286
369
|
|
|
287
|
-
|
|
370
|
+
// 窗口收集器
|
|
371
|
+
const windowed = data.toWindow();
|
|
372
|
+
const slidingWindows = windowed.slide(3n, 2n); // 窗口大小3,步长2
|
|
373
|
+
// 窗口1: [1, 2, 3], 窗口2: [3, 4, 5], 窗口3: [5, 6, 7], ...
|
|
288
374
|
|
|
289
|
-
|
|
290
|
-
|
|
375
|
+
const tumblingWindows = windowed.tumble(4n); // 翻滚窗口大小4
|
|
376
|
+
// 窗口1: [1, 2, 3, 4], 窗口2: [5, 6, 7, 8], ...
|
|
291
377
|
```
|
|
292
378
|
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
379
|
+
### Statistics<E, D> - 统计分析
|
|
380
|
+
|
|
381
|
+
统计分析基类,提供丰富的统计计算方法。**注意:必须先通过 Semantic 实例调用 toNumericStatistics() 或 toBigIntStatistics() 得到 Statistics 实例后才能使用以下方法。**
|
|
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
|
+
**代码示例补充:**
|
|
403
|
+
```typescript
|
|
404
|
+
import { from } from 'semantic-typescript';
|
|
405
|
+
|
|
406
|
+
const numbers = from([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
|
|
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, ...}
|
|
430
|
+
```
|
|
298
431
|
|
|
299
|
-
|
|
432
|
+
#### 具体统计实现类
|
|
300
433
|
|
|
301
|
-
|
|
434
|
+
**NumericStatistics<E>**
|
|
435
|
+
- 处理 number 类型的统计分析
|
|
436
|
+
- 所有统计计算返回 number 类型
|
|
302
437
|
|
|
303
|
-
|
|
438
|
+
**BigIntStatistics<E>**
|
|
439
|
+
- 处理 bigint 类型的统计分析
|
|
440
|
+
- 所有统计计算返回 bigint 类型
|
|
304
441
|
|
|
305
|
-
|
|
442
|
+
**代码示例补充:**
|
|
443
|
+
```typescript
|
|
444
|
+
import { from } from 'semantic-typescript';
|
|
306
445
|
|
|
307
|
-
|
|
446
|
+
// 数值统计
|
|
447
|
+
const numberData = from([10, 20, 30, 40, 50]);
|
|
448
|
+
const numericStats = numberData.toNumericStatistics();
|
|
308
449
|
|
|
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()` 等 |
|
|
450
|
+
console.log(numericStats.mean()); // 30
|
|
451
|
+
console.log(numericStats.summate()); // 150
|
|
318
452
|
|
|
319
|
-
|
|
453
|
+
// 大整数统计
|
|
454
|
+
const bigintData = from([100n, 200n, 300n, 400n, 500n]);
|
|
455
|
+
const bigintStats = bigintData.toBigIntStatistics();
|
|
320
456
|
|
|
321
|
-
|
|
457
|
+
console.log(bigintStats.mean()); // 300n
|
|
458
|
+
console.log(bigintStats.summate()); // 1500n
|
|
322
459
|
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
460
|
+
// 使用映射函数的统计
|
|
461
|
+
const objectData = from([
|
|
462
|
+
{ value: 15 },
|
|
463
|
+
{ value: 25 },
|
|
464
|
+
{ value: 35 },
|
|
465
|
+
{ value: 45 }
|
|
466
|
+
]);
|
|
326
467
|
|
|
327
|
-
|
|
468
|
+
const objectStats = objectData.toNumericStatistics();
|
|
469
|
+
const meanWithMapper = objectStats.mean(obj => obj.value); // 30
|
|
470
|
+
const sumWithMapper = objectStats.summate(obj => obj.value); // 120
|
|
471
|
+
```
|
|
328
472
|
|
|
329
|
-
|
|
473
|
+
## 完整使用示例
|
|
330
474
|
|
|
331
|
-
|
|
475
|
+
```typescript
|
|
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
|
+
}
|
|
504
|
+
|
|
505
|
+
// 5. 处理可能无效的数据
|
|
506
|
+
const potentiallyInvalidData: Array<number | null> = [1, null, 3, 4, null];
|
|
507
|
+
const validData = potentiallyInvalidData.filter(validate);
|
|
508
|
+
const invalidData = potentiallyInvalidData.filter(invalidate);
|
|
509
|
+
|
|
510
|
+
console.log("有效数据:", validData); // [1, 3, 4]
|
|
511
|
+
console.log("无效数据:", invalidData); // [null, null]
|
|
512
|
+
```
|
|
332
513
|
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
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
|
+
这样的设计确保了类型安全性和性能优化,同时提供了丰富的流处理功能。
|