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.tw.md
CHANGED
|
@@ -1,529 +1,426 @@
|
|
|
1
|
-
# Semantic-TypeScript
|
|
1
|
+
# Semantic-TypeScript 流處理庫
|
|
2
2
|
|
|
3
|
-
##
|
|
3
|
+
## 簡介
|
|
4
4
|
|
|
5
|
-
Semantic-TypeScript
|
|
5
|
+
Semantic-TypeScript 是一個受到 JavaScript GeneratorFunction、Java Stream 和 MySQL Index 啟發而設計的現代化流處理庫。該庫的核心設計理念是基於數據索引建構高效的數據處理管道,為前端開發提供類型安全、函數式風格的流式操作體驗。
|
|
6
6
|
|
|
7
|
-
與傳統的同步處理不同,Semantic
|
|
7
|
+
與傳統的同步處理不同,Semantic 採用非同步處理模式。在創建數據流時,終端接收數據的時間完全取決於上游何時調用 `accept` 和 `interrupt` 回調函數,這種設計使得庫能夠優雅地處理實時數據流、大型數據集和非同步數據源。
|
|
8
8
|
|
|
9
|
-
##
|
|
9
|
+
## 安裝
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
| **函數式程式設計** | 不可變資料結構和純函數 | 更可預測的程式碼,易於測試和維護 |
|
|
15
|
-
| **惰性求值** | 按需計算,效能最佳化 | 處理大型資料集時記憶體效率高 |
|
|
16
|
-
| **非同步串流處理** | 基於產生器的非同步資料流 | 適用於即時資料和事件驅動場景 |
|
|
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 確保資料不為 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
|
-
|
|
181
|
+
// 建立初始延遲2秒、執行週期5秒的時序串流,
|
|
182
|
+
// 基於計時器機制實現,因系統排程限制可能產生時間漂移
|
|
183
|
+
const intervalStream = interval(5000, 2000);
|
|
215
184
|
|
|
216
|
-
//
|
|
217
|
-
const
|
|
185
|
+
// 從可迭代物件建立串流
|
|
186
|
+
const numberStream = from([1, 2, 3, 4, 5]);
|
|
187
|
+
const stringStream = from(new Set(["Alex", "Bob"]));
|
|
218
188
|
|
|
219
|
-
//
|
|
220
|
-
const
|
|
189
|
+
// 建立範圍串流
|
|
190
|
+
const rangeStream = range(1, 10, 2); // 1, 3, 5, 7, 9
|
|
221
191
|
|
|
222
|
-
//
|
|
192
|
+
// WebSocket 事件串流
|
|
193
|
+
const ws = new WebSocket("ws://localhost:8080");
|
|
194
|
+
websocket(ws)
|
|
195
|
+
.filter((event)=> event.type === "message") // 僅監聽訊息事件
|
|
196
|
+
.toUnordered() // 事件通常不排序
|
|
197
|
+
.forEach((event)=> receive(event)); // 接收訊息
|
|
223
198
|
```
|
|
224
199
|
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
|
230
|
-
|
|
231
|
-
| `
|
|
232
|
-
| `
|
|
233
|
-
| `
|
|
200
|
+
## Semantic 類方法
|
|
201
|
+
|
|
202
|
+
| 方法 | 描述 | 時間複雜度 | 空間複雜度 |
|
|
203
|
+
|------|------|------------|------------|
|
|
204
|
+
| `concat(other)` | 連接兩個流 | O(n) | O(1) |
|
|
205
|
+
| `distinct()` | 去重 | O(n) | O(n) |
|
|
206
|
+
| `distinct(comparator)` | 使用比較器去重 | O(n²) | O(n) |
|
|
207
|
+
| `dropWhile(predicate)` | 丟棄滿足條件的元素 | O(n) | O(1) |
|
|
208
|
+
| `filter(predicate)` | 過濾元素 | O(n) | O(1) |
|
|
209
|
+
| `flat(mapper)` | 扁平化映射 | O(n × m) | O(1) |
|
|
210
|
+
| `flatMap(mapper)` | 扁平化映射到新型別 | O(n × m) | O(1) |
|
|
211
|
+
| `limit(n)` | 限制元素數量 | O(n) | O(1) |
|
|
212
|
+
| `map(mapper)` | 映射轉換 | O(n) | O(1) |
|
|
213
|
+
| `peek(consumer)` | 查看元素 | O(n) | O(1) |
|
|
214
|
+
| `redirect(redirector)` | 重定向索引 | O(n) | O(1) |
|
|
215
|
+
| `reverse()` | 反轉流 | O(n) | O(1) |
|
|
216
|
+
| `shuffle()` | 隨機打亂 | O(n) | O(1) |
|
|
217
|
+
| `shuffle(mapper)` | 使用映射器打亂 | O(n) | O(1) |
|
|
218
|
+
| `skip(n)` | 跳過前n個元素 | O(n) | O(1) |
|
|
219
|
+
| `sorted()` | 排序 | O(n log n) | O(n) |
|
|
220
|
+
| `sorted(comparator)` | 使用比較器排序 | O(n log n) | O(n) |
|
|
221
|
+
| `sub(start, end)` | 獲取子流 | O(n) | O(1) |
|
|
222
|
+
| `takeWhile(predicate)` | 獲取滿足條件的元素 | O(n) | O(1) |
|
|
223
|
+
| `translate(offset)` | 平移索引 | O(n) | O(1) |
|
|
224
|
+
| `translate(translator)` | 使用轉換器平移索引 | O(n) | O(1) |
|
|
234
225
|
|
|
235
|
-
**程式碼範例補充:**
|
|
236
226
|
```typescript
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
//
|
|
240
|
-
|
|
241
|
-
()
|
|
242
|
-
(
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
//
|
|
247
|
-
const
|
|
248
|
-
|
|
227
|
+
// Semantic 操作示例
|
|
228
|
+
const result = from([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
|
|
229
|
+
.filter(n => n % 2 === 0) // 過濾偶數
|
|
230
|
+
.map(n => n * 2) // 乘以2
|
|
231
|
+
.skip(1) // 跳過第一個
|
|
232
|
+
.limit(3) // 限制3個元素
|
|
233
|
+
.toArray(); // 轉換為陣列
|
|
234
|
+
// 結果: [8, 12, 20]
|
|
235
|
+
|
|
236
|
+
// 複雜操作示例
|
|
237
|
+
const complexResult = range(1, 100, 1)
|
|
238
|
+
.flatMap(n => from([n, n * 2])) // 每個元素映射為兩個
|
|
239
|
+
.distinct() // 去重
|
|
240
|
+
.shuffle() // 打亂順序
|
|
241
|
+
.takeWhile(n => n < 50) // 取小於50的元素
|
|
242
|
+
.toOrdered() // 轉換為有序收集器
|
|
243
|
+
.toArray(); // 轉換為陣列
|
|
249
244
|
```
|
|
250
245
|
|
|
251
|
-
|
|
246
|
+
## 收集器轉換方法
|
|
252
247
|
|
|
253
|
-
|
|
248
|
+
| 方法 | 描述 | 時間複雜度 | 空間複雜度 |
|
|
249
|
+
|------|------|------------|------------|
|
|
250
|
+
| `toUnoredered()` | 轉換為無序收集器(效能優先) | O(1) | O(1) |
|
|
251
|
+
| `toOrdered()` | 轉換為有序收集器 | O(1) | O(1) |
|
|
252
|
+
| `sorted()` | 排序並轉換為有序收集器 | O(n log n) | O(n) |
|
|
253
|
+
| `toWindow()` | 轉換為視窗收集器 | O(1) | O(1) |
|
|
254
|
+
| `toNumericStatistics()` | 轉換為數值統計 | O(1) | O(1) |
|
|
255
|
+
| `toBigintStatistics()` | 轉換為大數統計 | O(1) | O(1) |
|
|
254
256
|
|
|
255
|
-
|
|
257
|
+
```typescript
|
|
258
|
+
// 收集器轉換示例
|
|
259
|
+
const numbers = from([3, 1, 4, 1, 5, 9, 2, 6, 5]);
|
|
256
260
|
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
| `count()` | `bigint` | 元素數量統計 | `count()` → `5n` |
|
|
262
|
-
| `isEmpty()` | `boolean` | 串流是否為空 | `isEmpty()` |
|
|
263
|
-
| `findAny()` | `Optional<E>` | 尋找任意元素 | `findAny()` |
|
|
264
|
-
| `findFirst()` | `Optional<E>` | 尋找第一個元素 | `findFirst()` |
|
|
265
|
-
| `findLast()` | `Optional<E>` | 尋找最後一個元素 | `findLast()` |
|
|
261
|
+
// 效能優先:使用無序收集器
|
|
262
|
+
const unordered = numbers
|
|
263
|
+
.filter(n => n > 3)
|
|
264
|
+
.toUnoredered();
|
|
266
265
|
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
import { from } from 'semantic-typescript';
|
|
266
|
+
// 需要排序:使用有序收集器
|
|
267
|
+
const ordered = numbers.sorted();
|
|
270
268
|
|
|
271
|
-
|
|
269
|
+
// 統計分析:使用統計收集器
|
|
270
|
+
const stats = numbers
|
|
271
|
+
.toNumericStatistics();
|
|
272
|
+
|
|
273
|
+
console.log(stats.mean()); // 平均值
|
|
274
|
+
console.log(stats.median()); // 中位數
|
|
275
|
+
console.log(stats.standardDeviation()); // 標準差
|
|
272
276
|
|
|
273
|
-
//
|
|
274
|
-
const
|
|
277
|
+
// 視窗操作
|
|
278
|
+
const windowed = numbers
|
|
279
|
+
.toWindow()
|
|
280
|
+
.tumble(3n); // 每3個元素一個視窗
|
|
275
281
|
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
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(); // 任意元素
|
|
282
|
+
windowed.forEach(window => {
|
|
283
|
+
console.log(window.toArray()); // 每個視窗的內容
|
|
284
|
+
});
|
|
283
285
|
```
|
|
284
286
|
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
| 方法 |
|
|
288
|
-
|
|
289
|
-
| `
|
|
290
|
-
| `
|
|
291
|
-
| `
|
|
292
|
-
| `
|
|
293
|
-
| `
|
|
294
|
-
| `
|
|
295
|
-
| `
|
|
296
|
-
| `
|
|
297
|
-
| `
|
|
298
|
-
| `
|
|
299
|
-
| `
|
|
300
|
-
|
|
301
|
-
|
|
287
|
+
## Collectable 收集方法
|
|
288
|
+
|
|
289
|
+
| 方法 | 描述 | 時間複雜度 | 空間複雜度 |
|
|
290
|
+
|------|------|------------|------------|
|
|
291
|
+
| `anyMatch(predicate)` | 是否存在匹配元素 | O(n) | O(1) |
|
|
292
|
+
| `allMatch(predicate)` | 是否所有元素匹配 | O(n) | O(1) |
|
|
293
|
+
| `count()` | 元素計數 | O(n) | O(1) |
|
|
294
|
+
| `isEmpty()` | 是否為空 | O(1) | O(1) |
|
|
295
|
+
| `findAny()` | 查找任意元素 | O(n) | O(1) |
|
|
296
|
+
| `findFirst()` | 查找第一個元素 | O(n) | O(1) |
|
|
297
|
+
| `findLast()` | 查找最後一個元素 | O(n) | O(1) |
|
|
298
|
+
| `forEach(action)` | 遍歷所有元素 | O(n) | O(1) |
|
|
299
|
+
| `group(classifier)` | 按分類器分組 | O(n) | O(n) |
|
|
300
|
+
| `groupBy(keyExtractor, valueExtractor)` | 按鍵值提取器分組 | O(n) | O(n) |
|
|
301
|
+
| `join()` | 連接為字串 | O(n) | O(n) |
|
|
302
|
+
| `join(delimiter)` | 使用分隔符連接 | O(n) | O(n) |
|
|
303
|
+
| `nonMatch(predicate)` | 是否沒有元素匹配 | O(n) | O(1) |
|
|
304
|
+
| `partition(count)` | 按數量分區 | O(n) | O(n) |
|
|
305
|
+
| `partitionBy(classifier)` | 按分類器分區 | O(n) | O(n) |
|
|
306
|
+
| `reduce(accumulator)` | 歸約操作 | O(n) | O(1) |
|
|
307
|
+
| `reduce(identity, accumulator)` | 帶初始值的歸約 | O(n) | O(1) |
|
|
308
|
+
| `toArray()` | 轉換為陣列 | O(n) | O(n) |
|
|
309
|
+
| `toMap(keyExtractor, valueExtractor)` | 轉換為Map | O(n) | O(n) |
|
|
310
|
+
| `toSet()` | 轉換為Set | O(n) | O(n) |
|
|
311
|
+
| `write(stream)` | 寫入流 | O(n) | O(1) |
|
|
312
|
+
|
|
302
313
|
```typescript
|
|
303
|
-
|
|
314
|
+
// Collectable 操作示例
|
|
315
|
+
const data = from([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
|
|
316
|
+
.filter(n => n % 2 === 0)
|
|
317
|
+
.toOrdered();
|
|
304
318
|
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
{ name: "Charlie", age: 25, city: "New York" }
|
|
309
|
-
]);
|
|
319
|
+
// 匹配檢查
|
|
320
|
+
console.log(data.anyMatch(n => n > 5)); // true
|
|
321
|
+
console.log(data.allMatch(n => n < 20)); // true
|
|
310
322
|
|
|
311
|
-
//
|
|
312
|
-
|
|
323
|
+
// 查找操作
|
|
324
|
+
data.findFirst().ifPresent(n => console.log(n)); // 2
|
|
325
|
+
data.findAny().ifPresent(n => console.log(n)); // 任意元素
|
|
313
326
|
|
|
314
327
|
// 分組操作
|
|
315
|
-
const
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
const byAge = collectable.groupBy(
|
|
319
|
-
person => person.age,
|
|
320
|
-
person => person.name
|
|
328
|
+
const grouped = data.groupBy(
|
|
329
|
+
n => n > 5 ? "large" : "small",
|
|
330
|
+
n => n * 2
|
|
321
331
|
);
|
|
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 }
|
|
332
|
+
// {small: [4, 8], large: [12, 16, 20]}
|
|
331
333
|
|
|
332
334
|
// 歸約操作
|
|
333
|
-
const
|
|
334
|
-
const oldest = collectable.reduce((a, b) => a.age > b.age ? a : b); // Optional.of({name: "Bob", age: 30, ...})
|
|
335
|
-
```
|
|
336
|
-
|
|
337
|
-
### 特定收集器實作
|
|
338
|
-
|
|
339
|
-
#### UnorderedCollectable<E>
|
|
340
|
-
- **特性**:最快的收集器,無排序
|
|
341
|
-
- **使用場景**:順序不重要,需要最高效能
|
|
342
|
-
- **方法**:繼承所有 Collectable 方法
|
|
335
|
+
const sum = data.reduce(0, (acc, n) => acc + n); // 30
|
|
343
336
|
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
- **特殊方法**:繼承所有方法,維持內部排序狀態
|
|
337
|
+
// 輸出操作
|
|
338
|
+
data.join(", "); // "2, 4, 6, 8, 10"
|
|
339
|
+
```
|
|
348
340
|
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
341
|
+
## 統計分析方法
|
|
342
|
+
|
|
343
|
+
### NumericStatistics 方法
|
|
344
|
+
|
|
345
|
+
| 方法 | 描述 | 時間複雜度 | 空間複雜度 |
|
|
346
|
+
|------|------|------------|------------|
|
|
347
|
+
| `range()` | 極差 | O(n) | O(1) |
|
|
348
|
+
| `variance()` | 方差 | O(n) | O(1) |
|
|
349
|
+
| `standardDeviation()` | 標準差 | O(n) | O(1) |
|
|
350
|
+
| `mean()` | 平均值 | O(n) | O(1) |
|
|
351
|
+
| `median()` | 中位數 | O(n log n) | O(n) |
|
|
352
|
+
| `mode()` | 眾數 | O(n) | O(n) |
|
|
353
|
+
| `frequency()` | 頻率分佈 | O(n) | O(n) |
|
|
354
|
+
| `summate()` | 求和 | O(n) | O(1) |
|
|
355
|
+
| `quantile(quantile)` | 分位數 | O(n log n) | O(n) |
|
|
356
|
+
| `interquartileRange()` | 四分位距 | O(n log n) | O(n) |
|
|
357
|
+
| `skewness()` | 偏度 | O(n) | O(1) |
|
|
358
|
+
| `kurtosis()` | 峰度 | O(n) | O(1) |
|
|
355
359
|
|
|
356
|
-
**程式碼範例補充:**
|
|
357
360
|
```typescript
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
//
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
const
|
|
361
|
+
// 統計分析示例
|
|
362
|
+
const numbers = from([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
|
|
363
|
+
.toNumericStatistics();
|
|
364
|
+
|
|
365
|
+
console.log("平均值:", numbers.mean()); // 5.5
|
|
366
|
+
console.log("中位數:", numbers.median()); // 5.5
|
|
367
|
+
console.log("標準差:", numbers.standardDeviation()); // ~2.87
|
|
368
|
+
console.log("總和:", numbers.summate()); // 55
|
|
369
|
+
|
|
370
|
+
// 使用映射器的統計分析
|
|
371
|
+
const objects = from([
|
|
372
|
+
{ value: 10 },
|
|
373
|
+
{ value: 20 },
|
|
374
|
+
{ value: 30 }
|
|
375
|
+
]).toNumericStatistics();
|
|
376
|
+
|
|
377
|
+
console.log("映射平均值:", objects.mean(obj => obj.value)); // 20
|
|
378
|
+
```
|
|
369
379
|
|
|
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], ...
|
|
380
|
+
## 效能選擇指南
|
|
374
381
|
|
|
375
|
-
|
|
376
|
-
|
|
382
|
+
### 選擇無序收集器(效能優先)
|
|
383
|
+
```typescript
|
|
384
|
+
// 當不需要順序保證時,使用無序收集器獲得最佳效能
|
|
385
|
+
const highPerformance = data
|
|
386
|
+
.filter(predicate)
|
|
387
|
+
.map(mapper)
|
|
388
|
+
.toUnoredered(); // 最佳效能
|
|
377
389
|
```
|
|
378
390
|
|
|
379
|
-
###
|
|
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
|
-
**程式碼範例補充:**
|
|
391
|
+
### 選擇有序收集器(需要順序)
|
|
403
392
|
```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, ...}
|
|
393
|
+
// 當需要保持元素順序時,使用有序收集器
|
|
394
|
+
const ordered = data
|
|
395
|
+
.sorted(comparator) // 排序操作會覆蓋重定向效果
|
|
430
396
|
```
|
|
431
397
|
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
**NumericStatistics<E>**
|
|
435
|
-
- 處理 number 型別的統計分析
|
|
436
|
-
- 所有統計計算回傳 number 型別
|
|
437
|
-
|
|
438
|
-
**BigIntStatistics<E>**
|
|
439
|
-
- 處理 bigint 型別的統計分析
|
|
440
|
-
- 所有統計計算回傳 bigint 型別
|
|
441
|
-
|
|
442
|
-
**程式碼範例補充:**
|
|
398
|
+
### 選擇視窗收集器(視窗操作)
|
|
443
399
|
```typescript
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
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();
|
|
456
|
-
|
|
457
|
-
console.log(bigintStats.mean()); // 300n
|
|
458
|
-
console.log(bigintStats.summate()); // 1500n
|
|
459
|
-
|
|
460
|
-
// 使用對映函數的統計
|
|
461
|
-
const objectData = from([
|
|
462
|
-
{ value: 15 },
|
|
463
|
-
{ value: 25 },
|
|
464
|
-
{ value: 35 },
|
|
465
|
-
{ value: 45 }
|
|
466
|
-
]);
|
|
467
|
-
|
|
468
|
-
const objectStats = objectData.toNumericStatistics();
|
|
469
|
-
const meanWithMapper = objectStats.mean(obj => obj.value); // 30
|
|
470
|
-
const sumWithMapper = objectStats.summate(obj => obj.value); // 120
|
|
400
|
+
// 需要進行視窗操作時
|
|
401
|
+
const windowed = data
|
|
402
|
+
.toWindow()
|
|
403
|
+
.slide(5n, 2n); // 滑動視窗
|
|
471
404
|
```
|
|
472
405
|
|
|
473
|
-
|
|
474
|
-
|
|
406
|
+
### 選擇統計分析(數值計算)
|
|
475
407
|
```typescript
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
//
|
|
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();
|
|
408
|
+
// 需要進行統計分析時
|
|
409
|
+
const stats = data
|
|
410
|
+
.toNumericStatistics(); // 數值統計
|
|
490
411
|
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
.filter(x => x > 5) // 再次過濾
|
|
495
|
-
.toArray(); // 轉換為陣列
|
|
496
|
-
|
|
497
|
-
console.log("處理結果:", results); // [16, 18, 14, 8, 12]
|
|
412
|
+
const bigIntStats = data
|
|
413
|
+
.toBigintStatistics(); // 大數統計
|
|
414
|
+
```
|
|
498
415
|
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
console.log("平均值:", stats.mean()); // 11.2
|
|
502
|
-
console.log("總和:", stats.summate()); // 56
|
|
503
|
-
}
|
|
416
|
+
[GitHub](https://github.com/eloyhere/semantic-typescript)
|
|
417
|
+
[NPMJS](https://www.npmjs.com/package/semantic-typescript)
|
|
504
418
|
|
|
505
|
-
|
|
506
|
-
const potentiallyInvalidData: Array<number | null> = [1, null, 3, 4, null];
|
|
507
|
-
const validData = potentiallyInvalidData.filter(validate);
|
|
508
|
-
const invalidData = potentiallyInvalidData.filter(invalidate);
|
|
419
|
+
## 注意事項
|
|
509
420
|
|
|
510
|
-
|
|
511
|
-
|
|
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 開發者提供了強大而靈活的流式處理能力,結合了函數式編程的優點和類型安全的保障。
|