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/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
- | **类型安全泛型** | 完整的 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
- ### 流创建工厂
11
+ ```bash
12
+ npm install semantic-typescript
13
+ ```
38
14
 
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)` |
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
- import { from, range, fill, empty } from 'semantic-typescript';
52
-
53
- // 从数组创建流
54
- const numberStream = from([1, 2, 3, 4, 5]);
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` | `<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)` 随机数 |
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
- import { validate, invalidate, useCompare, useRandom } from 'semantic-typescript';
81
+ // 类型守卫使用示例
82
+ const value: unknown = "hello";
78
83
 
79
- // 验证数据有效性
80
- const data: string | null = "hello";
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
- const nullData: string | null = null;
86
- if (invalidate(nullData)) {
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
- | `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) |
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
- import { Optional } from 'semantic-typescript';
101
+ // 工具函数使用示例
102
+ const numbers = [3, 1, 4, 1, 5];
103
+ numbers.sort(useCompare); // [1, 1, 3, 4, 5]
119
104
 
120
- // 创建 Optional 实例
121
- const optionalValue = Optional.ofNullable<string>(Math.random() > 0.5 ? "hello" : null);
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
- console.log(result); // "HELLO" 或 "default"
111
+ ### Optional 工厂方法
130
112
 
131
- // 安全操作
132
- optionalValue.ifPresent(val => {
133
- console.log(`值存在: ${val}`);
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
- if (optionalValue.isPresent()) {
138
- console.log("有值");
139
- } else if (optionalValue.isEmpty()) {
140
- console.log("为空");
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
- ### 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
- **代码示例补充:**
173
- ```typescript
174
- import { from } from 'semantic-typescript';
131
+ ### Collector 工厂方法
175
132
 
176
- const stream = from([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
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
- 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}`)); // 查看元素
138
+ ```typescript
139
+ // Collector 使用示例
140
+ const sumCollector = Collector.full(
141
+ () => 0,
142
+ (sum, num) => sum + num,
143
+ result => result
144
+ );
185
145
 
186
- // 注意:此时流还未执行,需要转换为 Collectable 才能使用终端操作
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
- | `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>` | 自定义排序 | 覆盖重定向结果 |
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
- import { from } from 'semantic-typescript';
164
+ // Semantic 工厂方法使用示例
204
165
 
205
- const semanticStream = from([5, 2, 8, 1, 9, 3, 7, 4, 6]);
166
+ // Blob 创建流(分块读取)
167
+ blob(someBlob, 1024n)
168
+ .toUnordered()
169
+ .write(WritableStream)
170
+ .then(callback) // 写入流成功
171
+ .catch(writeFi); // 写入流失败
206
172
 
207
- // 转换为有序集合(性能较低)
208
- const ordered = semanticStream.toOrdered();
173
+ // 创建空流,在拼接其它流之前不会执行
174
+ empty<string>()
175
+ .toUnordered()
176
+ .join(); //[]
209
177
 
210
- // 转换为无序集合(最快)
211
- const unordered = semanticStream.toUnordered();
178
+ // 创建填充流
179
+ const filledStream = fill("hello", 3); // "hello", "hello", "hello"
212
180
 
213
- // 自然排序
214
- const sortedNatural = semanticStream.sorted();
181
+ // 创建初始延迟2秒、执行周期5秒的时序流,基于计时器机制实现,因系统调度精度限制可能存在时间漂移。
182
+ const intervalStream = interval(5000, 2000);
215
183
 
216
- // 自定义排序
217
- const sortedCustom = semanticStream.sorted((a, b) => b - a); // 降序排序
184
+ // 从可迭代对象创建流
185
+ const numberStream = from([1, 2, 3, 4, 5]);
186
+ const stringStream = from(new Set(["Alex", "Bob"]));
218
187
 
219
- // 转换为统计对象
220
- const stats = semanticStream.toNumericStatistics();
188
+ // 创建范围流
189
+ const rangeStream = range(1, 10, 2); // 1, 3, 5, 7, 9
221
190
 
222
- // 注意:必须通过 Semantic 实例调用上述方法得到 Collectable 后才能使用终端方法
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
- ### Collector<E, A, R> - 数据收集器
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
- 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
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
- ### Collectable<E> - 可收集数据抽象类
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
- import { from } from 'semantic-typescript';
270
-
271
- const numbers = from([1, 2, 3, 4, 5]);
272
-
273
- // 必须先转换为 Collectable 才能使用终端方法
274
- const collectable = numbers.toUnordered();
275
-
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(); // 任意元素
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
- | `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
- **代码示例补充:**
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
- import { from } from 'semantic-typescript';
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
- 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
- ]);
320
+ // 匹配检查
321
+ console.log(data.anyMatch(n => n > 5)); // true
322
+ console.log(data.allMatch(n => n < 20)); // true
310
323
 
311
- // 转换为 Collectable 后才能使用聚合操作
312
- const collectable = people.toUnordered();
324
+ // 查找操作
325
+ data.findFirst().ifPresent(n => console.log(n)); // 2
326
+ data.findAny().ifPresent(n => console.log(n)); // 任意元素
313
327
 
314
328
  // 分组操作
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
329
+ const grouped = data.groupBy(
330
+ n => n > 5 ? "large" : "small",
331
+ n => n * 2
321
332
  );
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 }
333
+ // {small: [4, 8], large: [12, 16, 20]}
331
334
 
332
335
  // 归约操作
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, ...})
335
- ```
336
+ const sum = data.reduce(0, (acc, n) => acc + n); // 30
336
337
 
337
- ### 具体收集器实现
338
-
339
- #### UnorderedCollectable<E>
340
- - **特点**:最快的收集器,不进行排序
341
- - **使用场景**:顺序不重要,追求最大性能
342
- - **方法**:继承 Collectable 的所有方法
343
-
344
- #### OrderedCollectable<E>
345
- - **特点**:保证元素有序,性能较低
346
- - **使用场景**:需要排序结果的场景
347
- - **特殊方法**:继承所有方法,内部维护排序状态
338
+ // 输出操作
339
+ data.join(", "); // "2, 4, 6, 8, 10"
340
+ ```
348
341
 
349
- #### WindowCollectable<E>
350
- - **特点**:支持滑动窗口操作
351
- - **使用场景**:时间序列数据分析
352
- - **特有方法**:
353
- - `slide(size, step)` - 滑动窗口
354
- - `tumble(size)` - 翻滚窗口
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
- import { from } from 'semantic-typescript';
359
-
360
- const data = from([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
361
-
362
- // 无序收集器(最快)
363
- const unordered = data.toUnordered();
364
- const unorderedArray = unordered.toArray(); // 可能保持原顺序 [1, 2, 3, ...]
365
-
366
- // 有序收集器
367
- const ordered = data.toOrdered();
368
- const orderedArray = ordered.toArray(); // 保证排序 [1, 2, 3, ...]
369
-
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], ...
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
- ### 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
- **代码示例补充:**
381
+ ## 性能选择指南
382
+
383
+ ### 选择无序收集器(性能优先)
403
384
  ```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, ...}
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
- import { from } from 'semantic-typescript';
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
- console.log(bigintStats.mean()); // 300n
458
- console.log(bigintStats.summate()); // 1500n
398
+ ### 选择窗口收集器(窗口操作)
399
+ ```typescript
400
+ // 需要进行窗口操作时
401
+ const windowed = data
402
+ .toWindow()
403
+ .slide(5n, 2n); // 滑动窗口
404
+ ```
459
405
 
460
- // 使用映射函数的统计
461
- const objectData = from([
462
- { value: 15 },
463
- { value: 25 },
464
- { value: 35 },
465
- { value: 45 }
466
- ]);
406
+ ### 选择统计分析(数值计算)
407
+ ```typescript
408
+ // 需要进行统计分析时
409
+ const stats = data
410
+ .toNumericStatistics(); // 数值统计
467
411
 
468
- const objectStats = objectData.toNumericStatistics();
469
- const meanWithMapper = objectStats.mean(obj => obj.value); // 30
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
- ```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
- }
419
+ ## 注意事项
504
420
 
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
- ```
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 开发者提供了强大而灵活的流式处理能力,结合了函数式编程的优点和类型安全的保障。