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.tw.md CHANGED
@@ -1,529 +1,426 @@
1
- # Semantic-TypeScript 串流處理框架
1
+ # Semantic-TypeScript 流處理庫
2
2
 
3
- ## 引言
3
+ ## 簡介
4
4
 
5
- Semantic-TypeScript 是一個現代化的串流處理函式庫,靈感來自 JavaScript GeneratorFunction、Java Stream 和 MySQL Index。其核心設計理念基於透過資料索引建構高效的資料處理管道,為前端開發提供型別安全、函數式風格的串流操作體驗。
5
+ Semantic-TypeScript 是一個受到 JavaScript GeneratorFunction、Java Stream 和 MySQL Index 啟發而設計的現代化流處理庫。該庫的核心設計理念是基於數據索引建構高效的數據處理管道,為前端開發提供類型安全、函數式風格的流式操作體驗。
6
6
 
7
- 與傳統的同步處理不同,Semantic 採用非同步處理模型。在建立資料流時,終端資料接收的時機完全取決於上游何時呼叫 `accept` 和 `interrupt` 回呼函數。這種設計使得函式庫能夠優雅地處理即時資料流、大型資料集和非同步資料來源。
7
+ 與傳統的同步處理不同,Semantic 採用非同步處理模式。在創建數據流時,終端接收數據的時間完全取決於上游何時調用 `accept` 和 `interrupt` 回調函數,這種設計使得庫能夠優雅地處理實時數據流、大型數據集和非同步數據源。
8
8
 
9
- ## 核心特性
9
+ ## 安裝
10
10
 
11
- | 特性 | 描述 | 優勢 |
12
- |------|------|------|
13
- | **型別安全泛型** | 完整的 TypeScript 型別支援 | 編譯時錯誤檢測,更好的開發體驗 |
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
- | `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 確保資料不為 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
+ // 基於計時器機制實現,因系統排程限制可能產生時間漂移
183
+ const intervalStream = interval(5000, 2000);
215
184
 
216
- // 自訂排序
217
- const sortedCustom = semanticStream.sorted((a, b) => b - a); // 降序排序
185
+ // 從可迭代物件建立串流
186
+ const numberStream = from([1, 2, 3, 4, 5]);
187
+ const stringStream = from(new Set(["Alex", "Bob"]));
218
188
 
219
- // 轉換為統計物件
220
- const stats = semanticStream.toNumericStatistics();
189
+ // 建立範圍串流
190
+ const rangeStream = range(1, 10, 2); // 1, 3, 5, 7, 9
221
191
 
222
- // 注意:必須透過 Semantic 實例呼叫上述方法以獲取 Collectable,然後才能使用終端方法
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
- ### Collector<E, A, R> - 資料收集器
226
-
227
- 收集器用於將串流資料聚合為特定結構。
228
-
229
- | 方法 | 描述 | 使用場景 |
230
- |------|------|----------|
231
- | `collect(generator)` | 執行資料收集 | 串流終端操作 |
232
- | `static full(identity, accumulator, finisher)` | 建立完整收集器 | 需要完整處理 |
233
- | `static shortable(identity, interruptor, accumulator, finisher)` | 建立可中斷收集器 | 可能提前終止 |
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
- 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
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
- ### Collectable<E> - 可收集資料抽象類別
246
+ ## 收集器轉換方法
252
247
 
253
- 提供豐富的資料聚合和轉換方法。**注意:必須先透過 Semantic 實例呼叫 sorted()、toOrdered() 等方法獲取 Collectable 實例,然後才能使用以下方法。**
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
- | `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()` |
261
+ // 效能優先:使用無序收集器
262
+ const unordered = numbers
263
+ .filter(n => n > 3)
264
+ .toUnoredered();
266
265
 
267
- **程式碼範例補充:**
268
- ```typescript
269
- import { from } from 'semantic-typescript';
266
+ // 需要排序:使用有序收集器
267
+ const ordered = numbers.sorted();
270
268
 
271
- const numbers = from([1, 2, 3, 4, 5]);
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
- // 必須先轉換為 Collectable 才能使用終端方法
274
- const collectable = numbers.toUnordered();
277
+ // 視窗操作
278
+ const windowed = numbers
279
+ .toWindow()
280
+ .tumble(3n); // 每3個元素一個視窗
275
281
 
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(); // 任意元素
282
+ windowed.forEach(window => {
283
+ console.log(window.toArray()); // 每個視窗的內容
284
+ });
283
285
  ```
284
286
 
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
- **程式碼範例補充:**
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
- import { from } from 'semantic-typescript';
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
- 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
- ]);
319
+ // 匹配檢查
320
+ console.log(data.anyMatch(n => n > 5)); // true
321
+ console.log(data.allMatch(n => n < 20)); // true
310
322
 
311
- // 必須先轉換為 Collectable 才能使用聚合操作
312
- const collectable = people.toUnordered();
323
+ // 查找操作
324
+ data.findFirst().ifPresent(n => console.log(n)); // 2
325
+ data.findAny().ifPresent(n => console.log(n)); // 任意元素
313
326
 
314
327
  // 分組操作
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
328
+ const grouped = data.groupBy(
329
+ n => n > 5 ? "large" : "small",
330
+ n => n * 2
321
331
  );
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 }
332
+ // {small: [4, 8], large: [12, 16, 20]}
331
333
 
332
334
  // 歸約操作
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
-
337
- ### 特定收集器實作
338
-
339
- #### UnorderedCollectable<E>
340
- - **特性**:最快的收集器,無排序
341
- - **使用場景**:順序不重要,需要最高效能
342
- - **方法**:繼承所有 Collectable 方法
335
+ const sum = data.reduce(0, (acc, n) => acc + n); // 30
343
336
 
344
- #### OrderedCollectable<E>
345
- - **特性**:保證元素順序,效能較低
346
- - **使用場景**:需要排序結果
347
- - **特殊方法**:繼承所有方法,維持內部排序狀態
337
+ // 輸出操作
338
+ data.join(", "); // "2, 4, 6, 8, 10"
339
+ ```
348
340
 
349
- #### WindowCollectable<E>
350
- - **特性**:支援滑動視窗操作
351
- - **使用場景**:時間序列資料分析
352
- - **特殊方法**:
353
- - `slide(size, step)` - 滑動視窗
354
- - `tumble(size)` - 翻滾視窗
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
- 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, ...]
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
- const tumblingWindows = windowed.tumble(4n); // 翻滾視窗大小 4
376
- // 視窗 1: [1, 2, 3, 4], 視窗 2: [5, 6, 7, 8], ...
382
+ ### 選擇無序收集器(效能優先)
383
+ ```typescript
384
+ // 當不需要順序保證時,使用無序收集器獲得最佳效能
385
+ const highPerformance = data
386
+ .filter(predicate)
387
+ .map(mapper)
388
+ .toUnoredered(); // 最佳效能
377
389
  ```
378
390
 
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
- **程式碼範例補充:**
391
+ ### 選擇有序收集器(需要順序)
403
392
  ```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, ...}
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
- 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();
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
- 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();
408
+ // 需要進行統計分析時
409
+ const stats = data
410
+ .toNumericStatistics(); // 數值統計
490
411
 
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]
412
+ const bigIntStats = data
413
+ .toBigintStatistics(); // 大數統計
414
+ ```
498
415
 
499
- // 統計資訊
500
- const stats = processedStream.toNumericStatistics();
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
- // 5. 處理潛在的無效資料
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
- 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 開發者提供了強大而靈活的流式處理能力,結合了函數式編程的優點和類型安全的保障。