semantic-typescript 0.0.7 → 0.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/readme.tw.md CHANGED
@@ -1,335 +1,426 @@
1
- # 📘 semantic-typescript
1
+ # Semantic-TypeScript 流處理庫
2
2
 
3
- 一個強大且**類型安全**的 TypeScript 工具庫,專為**語意化資料處理(Semantic Data Processing)**而設計。
4
- 提供可組合的函數式結構,用於處理集合(Collections)、資料流(Streams)與序列(Sequences),並支援排序、篩選、分組、統計分析等多種功能。
3
+ ## 簡介
5
4
 
6
- 無論您是處理**已排序或未排序的資料**、進行**統計分析**,還是僅想**流暢地鏈式操作資料**,這個套件都能滿足您的需求。
5
+ Semantic-TypeScript 是一個受到 JavaScript GeneratorFunction、Java Stream 和 MySQL Index 啟發而設計的現代化流處理庫。該庫的核心設計理念是基於數據索引建構高效的數據處理管道,為前端開發提供類型安全、函數式風格的流式操作體驗。
7
6
 
8
- ---
7
+ 與傳統的同步處理不同,Semantic 採用非同步處理模式。在創建數據流時,終端接收數據的時間完全取決於上游何時調用 `accept` 和 `interrupt` 回調函數,這種設計使得庫能夠優雅地處理實時數據流、大型數據集和非同步數據源。
9
8
 
10
- ## 🧩 功能特色
11
-
12
- - ✅ 全面採用**類型安全的泛型(Generics)**
13
- - ✅ **函數式編程風格**(例如:map、filter、reduce)
14
- - ✅ **語意化資料流(Semantic<E>)**,支援延遲求值(Lazy Evaluation)
15
- - ✅ 可將資料流轉換為實體資料結構的**收集器(Collectors)**
16
- - ✅ **已排序與未排序的收集器(Collectables)** — 其中 `toUnordered()` 是**最快的(不會排序)**
17
- - ✅ 支援透過 `sorted()`、`toOrdered()` 與自訂比較器進行**排序**
18
- - ✅ **統計分析功能**(`Statistics`、`NumericStatistics`、`BigIntStatistics`)
19
- - ✅ **Optional<T>** — 安全處理可能為 `null` 或 `undefined` 值的 Monad
20
- - ✅ 採用**迭代器(Iterator)與生成器(Generator)**架構,適用於大型或非同步資料
21
-
22
- ---
23
-
24
- ## 📦 安裝方式
9
+ ## 安裝
25
10
 
26
11
  ```bash
27
12
  npm install semantic-typescript
28
13
  ```
29
14
 
30
- ---
31
-
32
- ## 🧠 核心概念
33
-
34
- ### 1. `Optional<T>` — 安全處理可為空(Nullable)的值
35
-
36
- 用來包裝可能為 `null` 或 `undefined` 的值的 Monad 容器。
37
-
38
- #### 提供的方法:
39
-
40
- | 方法 | 說明 | 範例 |
41
- |------|------|------|
42
- | `of(value)` | 包裝一個值(可為空) | `Optional.of(null)` |
43
- | `ofNullable(v)` | 包裝,允許為空值 | `Optional.ofNullable(someVar)` |
44
- | `ofNonNull(v)` | 包裝,若為 null/undefined 則拋出例外 | `Optional.ofNonNull(5)` |
45
- | `get()` | 取得值(若為空則拋出例外) | `opt.get()` |
46
- | `getOrDefault(d)` | 取得值,若無則回傳預設值 | `opt.getOrDefault(0)` |
47
- | `ifPresent(fn)` | 若有值則執行副作用 | `opt.ifPresent(x => console.log(x))` |
48
- | `map(fn)` | 若有值則對其進行轉換 | `opt.map(x => x + 1)` |
49
- | `filter(fn)` | 僅保留符合條件的值 | `opt.filter(x => x > 0)` |
50
- | `isEmpty()` | 判斷是否為空 | `opt.isEmpty()` |
51
- | `isPresent()` | 判斷是否有值 | `opt.isPresent()` |
15
+ ## 基礎類型
52
16
 
53
- #### 範例:
17
+ | 類型 | 描述 |
18
+ |------|------|
19
+ | `Invalid<T>` | 擴展 null 或 undefined 的類型 |
20
+ | `Valid<T>` | 排除 null 和 undefined 的類型 |
21
+ | `MaybeInvalid<T>` | 可能為 null 或 undefined 的類型 |
22
+ | `Primitive` | 原始類型集合 |
23
+ | `MaybePrimitive<T>` | 可能為原始類型的類型 |
24
+ | `OptionalSymbol` | Optional 類的符號標識 |
25
+ | `SemanticSymbol` | Semantic 類的符號標識 |
26
+ | `CollectorsSymbol` | Collector 類的符號標識 |
27
+ | `CollectableSymbol` | Collectable 類的符號標識 |
28
+ | `OrderedCollectableSymbol` | OrderedCollectable 類的符號標識 |
29
+ | `WindowCollectableSymbol` | WindowCollectable 類的符號標識 |
30
+ | `StatisticsSymbol` | Statistics 類的符號標識 |
31
+ | `NumericStatisticsSymbol` | NumericStatistics 類的符號標識 |
32
+ | `BigIntStatisticsSymbol` | BigIntStatistics 類的符號標識 |
33
+ | `UnorderedCollectableSymbol` | UnorderedCollectable 類的符號標識 |
34
+ | `Runnable` | 無參數無返回值的函數 |
35
+ | `Supplier<R>` | 無參數返回 R 的函數 |
36
+ | `Functional<T, R>` | 單參數轉換函數 |
37
+ | `Predicate<T>` | 單參數判斷函數 |
38
+ | `BiFunctional<T, U, R>` | 雙參數轉換函數 |
39
+ | `BiPredicate<T, U>` | 雙參數判斷函數 |
40
+ | `Comparator<T>` | 比較函數 |
41
+ | `TriFunctional<T, U, V, R>` | 三參數轉換函數 |
42
+ | `Consumer<T>` | 單參數消費函數 |
43
+ | `BiConsumer<T, U>` | 雙參數消費函數 |
44
+ | `TriConsumer<T, U, V>` | 三參數消費函數 |
45
+ | `Generator<T>` | 生成器函數 |
54
46
 
55
47
  ```typescript
56
- import { Optional } from 'semantic-typescript';
57
-
58
- const value: number | null = Math.random() > 0.5 ? 10 : null;
59
-
60
- const opt = Optional.ofNullable(value);
61
-
62
- const result = opt
63
- .filter(v => v > 5)
64
- .map(v => v * 2)
65
- .getOrDefault(0);
66
-
67
- console.log(result); // 20 或 0
48
+ // 類型使用示例
49
+ const predicate: Predicate<number> = (n) => n > 0;
50
+ const mapper: Functional<string, number> = (str) => str.length;
51
+ const comparator: Comparator<number> = (a, b) => a - b;
68
52
  ```
69
53
 
70
- ---
54
+ ## 類型守衛
55
+
56
+ | 函數 | 描述 | 時間複雜度 | 空間複雜度 |
57
+ |------|------|------------|------------|
58
+ | `validate<T>(t: MaybeInvalid<T>): t is T` | 驗證值不為 null 或 undefined | O(1) | O(1) |
59
+ | `invalidate<T>(t: MaybeInvalid<T>): t is null \| undefined` | 驗證值為 null 或 undefined | O(1) | O(1) |
60
+ | `isBoolean(t: unknown): t is boolean` | 檢查是否為布林值 | O(1) | O(1) |
61
+ | `isString(t: unknown): t is string` | 檢查是否為字串 | O(1) | O(1) |
62
+ | `isNumber(t: unknown): t is number` | 檢查是否為數字 | O(1) | O(1) |
63
+ | `isFunction(t: unknown): t is Function` | 檢查是否為函數 | O(1) | O(1) |
64
+ | `isObject(t: unknown): t is object` | 檢查是否為物件 | O(1) | O(1) |
65
+ | `isSymbol(t: unknown): t is symbol` | 檢查是否為 Symbol | O(1) | O(1) |
66
+ | `isBigint(t: unknown): t is bigint` | 檢查是否為 BigInt | O(1) | O(1) |
67
+ | `isPrimitive(t: unknown): t is Primitive` | 檢查是否為原始類型 | O(1) | O(1) |
68
+ | `isIterable(t: unknown): t is Iterable<unknown>` | 檢查是否為可迭代物件 | O(1) | O(1) |
69
+ | `isOptional(t: unknown): t is Optional<unknown>` | 檢查是否為 Optional 實例 | O(1) | O(1) |
70
+ | `isSemantic(t: unknown): t is Semantic<unknown>` | 檢查是否為 Semantic 實例 | O(1) | O(1) |
71
+ | `isCollector(t: unknown): t is Collector<unknown, unknown, unknown>` | 檢查是否為 Collector 實例 | O(1) | O(1) |
72
+ | `isCollectable(t: unknown): t is Collectable<unknown>` | 檢查是否為 Collectable 實例 | O(1) | O(1) |
73
+ | `isOrderedCollectable(t: unknown): t is OrderedCollectable<unknown>` | 檢查是否為 OrderedCollectable 實例 | O(1) | O(1) |
74
+ | `isWindowCollectable(t: unknown): t is WindowCollectable<unknown>` | 檢查是否為 WindowCollectable 實例 | O(1) | O(1) |
75
+ | `isUnorderedCollectable(t: unknown): t is UnorderedCollectable<unknown>` | 檢查是否為 UnorderedCollectable 實例 | O(1) | O(1) |
76
+ | `isStatistics(t: unknown): t is Statistics<unknown, number \| bigint>` | 檢查是否為 Statistics 實例 | O(1) | O(1) |
77
+ | `isNumericStatistics(t: unknown): t is NumericStatistics<unknown>` | 檢查是否為 NumericStatistics 實例 | O(1) | O(1) |
78
+ | `isBigIntStatistics(t: unknown): t is BigIntStatistics<unknown>` | 檢查是否為 BigIntStatistics 實例 | O(1) | O(1) |
71
79
 
72
- ### 2. `Semantic<E>` — 延遲資料流(Lazy Data Stream)
80
+ ```typescript
81
+ // 類型守衛使用示例
82
+ const value: unknown = "hello";
73
83
 
74
- 一個**可組合、延遲求值的資料序列**,類似於 Java 的 Streams 或 Kotlin 的 Sequences。
84
+ if (isString(value)) {
85
+ console.log(value.length); // 類型安全,value 被推斷為 string
86
+ }
75
87
 
76
- 您可使用 `from()`、`range()`、`iterate()` 或 `fill()` 等輔助函數建立 `Semantic` 資料流。
88
+ if (isOptional(someValue)) {
89
+ someValue.ifPresent(val => console.log(val));
90
+ }
91
+ ```
77
92
 
78
- #### 建立方式:
93
+ ## 工具函數
79
94
 
80
- | 函數 | 說明 | 範例 |
81
- |------|------|------|
82
- | `from(iterable)` | 從陣列、集合或可迭代物件建立 | `from([1, 2, 3])` |
83
- | `range(start, end, step?)` | 產生數字範圍 | `range(0, 5)` 0,1,2,3,4 |
84
- | `fill(element, count)` | 重複某個元素 N 次 | `fill('a', 3n)` |
85
- | `iterate(gen)` | 使用自訂的生成器函數 | `iterate(genFn)` |
95
+ | 函數 | 描述 | 時間複雜度 | 空間複雜度 |
96
+ |------|------|------------|------------|
97
+ | `useCompare<T>(t1: T, t2: T): number` | 通用比較函數 | O(1) | O(1) |
98
+ | `useRandom<T = number | bigint>(index: T): T` | 偽隨機數生成器 | O(log n) | O(1) |
86
99
 
87
- #### 常見操作:
100
+ ```typescript
101
+ // 工具函數使用示例
102
+ const numbers = [3, 1, 4, 1, 5];
103
+ numbers.sort(useCompare); // [1, 1, 3, 4, 5]
88
104
 
89
- | 方法 | 說明 | 範例 |
90
- |------|------|------|
91
- | `map(fn)` | 對每個元素進行轉換 | `.map(x => x * 2)` |
92
- | `filter(fn)` | 僅保留符合條件的元素 | `.filter(x => x > 10)` |
93
- | `limit(n)` | 限制回傳前 N 個元素 | `.limit(5)` |
94
- | `skip(n)` | 跳過前 N 個元素 | `.skip(2)` |
95
- | `distinct()` | 移除重複項(預設使用 Set) | `.distinct()` |
96
- | `sorted()` | 對元素進行排序(自然順序) | `.sorted()` |
97
- | `sorted(comparator)` | 使用自訂比較器排序 | `.sorted((a, b) => a - b)` |
98
- | `toOrdered()` | 排序後回傳 OrderedCollectable | `.toOrdered()` |
99
- | `toUnordered()` | **不進行排序(最快的方法)** | `.toUnordered()` ✅ |
100
- | `collect(collector)` | 使用 Collector 進行聚合 | `.collect(Collector.full(...))` |
101
- | `toArray()` | 轉為陣列 | `.toArray()` |
102
- | `toSet()` | 轉為 Set | `.toSet()` |
103
- | `toMap(keyFn, valFn)` | 轉為 Map | `.toMap(x => x.id, x => x)` |
105
+ const randomNum = useRandom(42); // 基於種子的隨機數
106
+ const randomBigInt = useRandom(1000n); // BigInt 隨機數
107
+ ```
104
108
 
105
- ---
109
+ ## 工廠方法
106
110
 
107
- ### 3. `toUnordered()` — 🚀 最快,不排序
111
+ ### Optional 工廠方法
108
112
 
109
- 如果您**不需要排序**,且希望獲得**最快的效能**,請使用:
113
+ | 方法 | 描述 | 時間複雜度 | 空間複雜度 |
114
+ |------|------|------------|------------|
115
+ | `Optional.empty<T>()` | 創建空的 Optional | O(1) | O(1) |
116
+ | `Optional.of<T>(value)` | 創建包含值的 Optional | O(1) | O(1) |
117
+ | `Optional.ofNullable<T>(value)` | 創建可能為空的 Optional | O(1) | O(1) |
118
+ | `Optional.ofNonNull<T>(value)` | 創建非空的 Optional | O(1) | O(1) |
110
119
 
111
120
  ```typescript
112
- const fastest = semanticStream.toUnordered();
121
+ // Optional 使用示例
122
+ const emptyOpt = Optional.empty<number>();
123
+ const presentOpt = Optional.of(42);
124
+ const nullableOpt = Optional.ofNullable<string>(null);
125
+ const nonNullOpt = Optional.ofNonNull("hello");
126
+
127
+ presentOpt.ifPresent(val => console.log(val)); // 輸出 42
128
+ console.log(emptyOpt.orElse(100)); // 輸出 100
113
129
  ```
114
130
 
115
- 🔥 **不會套用任何排序演算法。**
116
- 當資料的順序不重要,而您追求極致效能時,這是最佳選擇。
117
-
118
- ---
131
+ ### Collector 工廠方法
119
132
 
120
- ### 4. `toOrdered()` `sorted()` 排序後的資料
121
-
122
- 如果您需要**排序後的資料**,可使用以下方法:
133
+ | 方法 | 描述 | 時間複雜度 | 空間複雜度 |
134
+ |------|------|------------|------------|
135
+ | `Collector.full(identity, accumulator, finisher)` | 創建完整收集器 | O(1) | O(1) |
136
+ | `Collector.shortable(identity, interruptor, accumulator, finisher)` | 創建可中斷收集器 | O(1) | O(1) |
123
137
 
124
138
  ```typescript
125
- const ordered = semanticStream.sorted(); // 自然排序
126
- const customSorted = semanticStream.sorted((a, b) => a - b); // 自訂比較器
127
- const orderedCollectable = semanticStream.toOrdered(); // 也會排序
139
+ // Collector 使用示例
140
+ const sumCollector = Collector.full(
141
+ () => 0,
142
+ (sum, num) => sum + num,
143
+ result => result
144
+ );
145
+
146
+ const numbers = from([1, 2, 3, 4, 5]);
147
+ const total = numbers.toUnoredered().collect(sumCollector); // 15
128
148
  ```
129
149
 
130
- ⚠️ 這些方法**會對資料進行排序**,可選擇使用自然排序或自訂比較器。
131
-
132
- ---
150
+ ### Semantic 工廠方法
133
151
 
134
- ### 5. `Collector<E, A, R>` 資料聚合
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) |
135
162
 
136
- Collector 可讓您將資料流**縮減為單一值或複雜的資料結構**。
163
+ ```typescript
164
+ // Semantic 工廠方法使用範例
165
+
166
+ // 從 Blob 建立串流(分塊讀取)
167
+ blob(someBlob, 1024n)
168
+ .toUnordered()
169
+ .write(WritableStream)
170
+ .then(callback) // 串流寫入成功
171
+ .catch(writeFi); // 串流寫入失敗
172
+
173
+ // 建立空串流,僅在與其他串流連接後才會執行
174
+ empty<string>()
175
+ .toUnordered()
176
+ .join(); //[]
177
+
178
+ // 建立填充串流
179
+ const filledStream = fill("hello", 3); // "hello", "hello", "hello"
180
+
181
+ // 建立初始延遲2秒、執行週期5秒的時序串流,
182
+ // 基於計時器機制實現,因系統排程限制可能產生時間漂移
183
+ const intervalStream = interval(5000, 2000);
184
+
185
+ // 從可迭代物件建立串流
186
+ const numberStream = from([1, 2, 3, 4, 5]);
187
+ const stringStream = from(new Set(["Alex", "Bob"]));
188
+
189
+ // 建立範圍串流
190
+ const rangeStream = range(1, 10, 2); // 1, 3, 5, 7, 9
191
+
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)); // 接收訊息
198
+ ```
137
199
 
138
- 內建靜態工廠:
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) |
139
225
 
140
226
  ```typescript
141
- Collector.full(identity, accumulator, finisher)
142
- Collector.shortable(identity, interruptor, accumulator, finisher)
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(); // 轉換為陣列
143
244
  ```
144
245
 
145
- 但您通常會透過 `Collectable` 類別提供的高階方法來使用它們。
246
+ ## 收集器轉換方法
146
247
 
147
- ---
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) |
148
256
 
149
- ### 6. `Collectable<E>`(抽象類別)
150
-
151
- 以下類別的基礎:
257
+ ```typescript
258
+ // 收集器轉換示例
259
+ const numbers = from([3, 1, 4, 1, 5, 9, 2, 6, 5]);
152
260
 
153
- - `OrderedCollectable<E>` — 排序後的資料
154
- - `UnorderedCollectable<E>` 不排序,速度最快
155
- - `WindowCollectable<E>` 滑動視窗資料
156
- - `Statistics<E, D>` — 統計資料聚合
261
+ // 效能優先:使用無序收集器
262
+ const unordered = numbers
263
+ .filter(n => n > 3)
264
+ .toUnoredered();
157
265
 
158
- #### 常見方法(繼承而來):
266
+ // 需要排序:使用有序收集器
267
+ const ordered = numbers.sorted();
159
268
 
160
- | 方法 | 說明 | 範例 |
161
- |------|------|------|
162
- | `count()` | 計算元素數量 | `.count()` |
163
- | `toArray()` | 轉為陣列 | `.toArray()` |
164
- | `toSet()` | 轉為 Set | `.toSet()` |
165
- | `toMap(k, v)` | 轉為 Map | `.toMap(x => x.id, x => x)` |
166
- | `group(k)` | 依鍵值分組 | `.group(x => x.category)` |
167
- | `findAny()` | 找出任意符合的元素(Optional) | `.findAny()` |
168
- | `findFirst()` | 找出第一個元素(Optional) | `.findFirst()` |
169
- | `reduce(...)` | 自訂縮減邏輯 | `.reduce((a,b) => a + b, 0)` |
269
+ // 統計分析:使用統計收集器
270
+ const stats = numbers
271
+ .toNumericStatistics();
170
272
 
171
- ---
273
+ console.log(stats.mean()); // 平均值
274
+ console.log(stats.median()); // 中位數
275
+ console.log(stats.standardDeviation()); // 標準差
172
276
 
173
- ### 7. `OrderedCollectable<E>` — 排序資料
277
+ // 視窗操作
278
+ const windowed = numbers
279
+ .toWindow()
280
+ .tumble(3n); // 每3個元素一個視窗
174
281
 
175
- 如果您希望資料**自動排序**,可使用此類別。
282
+ windowed.forEach(window => {
283
+ console.log(window.toArray()); // 每個視窗的內容
284
+ });
285
+ ```
176
286
 
177
- 可接受**自訂比較器**,或使用自然排序。
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) |
178
312
 
179
313
  ```typescript
180
- const sorted = new OrderedCollectable(stream);
181
- const customSorted = new OrderedCollectable(stream, (a, b) => b - a);
314
+ // Collectable 操作示例
315
+ const data = from([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
316
+ .filter(n => n % 2 === 0)
317
+ .toOrdered();
318
+
319
+ // 匹配檢查
320
+ console.log(data.anyMatch(n => n > 5)); // true
321
+ console.log(data.allMatch(n => n < 20)); // true
322
+
323
+ // 查找操作
324
+ data.findFirst().ifPresent(n => console.log(n)); // 2
325
+ data.findAny().ifPresent(n => console.log(n)); // 任意元素
326
+
327
+ // 分組操作
328
+ const grouped = data.groupBy(
329
+ n => n > 5 ? "large" : "small",
330
+ n => n * 2
331
+ );
332
+ // {small: [4, 8], large: [12, 16, 20]}
333
+
334
+ // 歸約操作
335
+ const sum = data.reduce(0, (acc, n) => acc + n); // 30
336
+
337
+ // 輸出操作
338
+ data.join(", "); // "2, 4, 6, 8, 10"
182
339
  ```
183
340
 
184
- 🔒 **保證輸出為排序後的資料。**
185
-
186
- ---
187
-
188
- ### 8. `UnorderedCollectable<E>` 不排序(🚀 最快)
189
-
190
- 如果您**不在意資料順序**,且希望獲得**最佳效能**,可使用:
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) |
191
359
 
192
360
  ```typescript
193
- const unordered = new UnorderedCollectable(stream);
194
- //
195
- const fastest = semanticStream.toUnordered();
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
196
378
  ```
197
379
 
198
- **不執行任何排序演算法**
199
- ✅ **當資料順序不重要時,提供最快速的處理方式**
200
-
201
- ---
202
-
203
- ### 9. `Statistics<E, D>` — 統計分析
204
-
205
- 用於分析數值資料的抽象基礎類別。
206
-
207
- #### 子類別:
208
-
209
- - `NumericStatistics<E>` — 適用於 `number` 類型
210
- - `BigIntStatistics<E>` — 適用於 `bigint` 類型
211
-
212
- ##### 常見統計方法:
213
-
214
- | 方法 | 說明 | 範例 |
215
- |------|------|------|
216
- | `mean()` | 平均值 | `.mean()` |
217
- | `median()` | 中位數 | `.median()` |
218
- | `mode()` | 眾數(最常出現的值) | `.mode()` |
219
- | `minimum()` | 最小值 | `.minimum()` |
220
- | `maximum()` | 最大值 | `.maximum()` |
221
- | `range()` | 範圍(最大值 - 最小值) | `.range()` |
222
- | `variance()` | 變異數 | `.variance()` |
223
- | `standardDeviation()` | 標準差 | `.standardDeviation()` |
224
- | `summate()` | 總和 | `.summate()` |
225
- | `quantile(q)` | 第 q 百分位數(0–1) | `.quantile(0.5)` → 中位數 |
226
- | `frequency()` | 頻率統計(Map) | `.frequency()` |
227
-
228
- ---
229
-
230
- ## 🧪 完整範例
380
+ ## 效能選擇指南
231
381
 
382
+ ### 選擇無序收集器(效能優先)
232
383
  ```typescript
233
- import { from, toUnordered, toOrdered, sorted, NumericStatistics } from 'semantic-typescript';
234
-
235
- // 範例資料
236
- const numbers = from([10, 2, 8, 4, 5, 6]);
237
-
238
- // 🚀 最快:不排序
239
- const fastest = numbers.toUnordered();
240
- console.log(fastest.toArray()); // 例如:[10, 2, 8, 4, 5, 6](原始順序)
241
-
242
- // 🔢 自然排序
243
- const ordered = numbers.sorted();
244
- console.log(ordered.toArray()); // [2, 4, 5, 6, 8, 10]
245
-
246
- // 📊 統計分析
247
- const stats = new NumericStatistics(numbers);
248
- console.log('平均值:', stats.mean());
249
- console.log('中位數:', stats.median());
250
- console.log('眾數:', stats.mode());
251
- console.log('範圍:', stats.range());
252
- console.log('標準差:', stats.standardDeviation());
384
+ // 當不需要順序保證時,使用無序收集器獲得最佳效能
385
+ const highPerformance = data
386
+ .filter(predicate)
387
+ .map(mapper)
388
+ .toUnoredered(); // 最佳效能
253
389
  ```
254
390
 
255
- ---
256
-
257
- ## 🛠️ 工具函數
258
-
259
- 本套件也提供多種**型別守衛(Type Guards)**與**比較工具**:
260
-
261
- | 函數 | 用途 |
262
- |------|------|
263
- | `isString(x)` | 判斷是否為 `string` |
264
- | `isNumber(x)` | 判斷是否為 `number` |
265
- | `isBoolean(x)` | 判斷是否為 `boolean` |
266
- | `isIterable(x)` | 判斷是否為可迭代物件 |
267
- | `useCompare(a, b)` | 通用比較函數 |
268
- | `useRandom(x)` | 偽隨機數生成器(趣味用途) |
269
-
270
- ---
271
-
272
- ## 🧩 進階:自訂生成器與滑動視窗
273
-
274
- 您可以建立**自訂的資料生成器**,用於控制或無限的資料流:
275
-
391
+ ### 選擇有序收集器(需要順序)
276
392
  ```typescript
277
- const gen = (accept: BiConsumer<number, bigint>, interrupt: Predicate<number>) => {
278
- for (let i = 0; i < 10; i++) {
279
- accept(i, BigInt(i));
280
- if (i === 5) interrupt(i);
281
- }
282
- };
283
-
284
- const s = new Semantic(gen);
393
+ // 當需要保持元素順序時,使用有序收集器
394
+ const ordered = data
395
+ .sorted(comparator) // 排序操作會覆蓋重定向效果
285
396
  ```
286
397
 
287
- 或者使用**滑動視窗(Sliding Window)**:
288
-
398
+ ### 選擇視窗收集器(視窗操作)
289
399
  ```typescript
290
- const windowed = ordered.slide(3n, 2n); // 視窗大小為 3,每次移動 2
400
+ // 需要進行視窗操作時
401
+ const windowed = data
402
+ .toWindow()
403
+ .slide(5n, 2n); // 滑動視窗
291
404
  ```
292
405
 
293
- ---
294
-
295
- ## 📄 授權
296
-
297
- 本專案採用 **MIT 授權**,可免費用於商業或個人用途。
298
-
299
- ---
300
-
301
- ## 🙌 貢獻
302
-
303
- 歡迎提交 Pull Request、提出問題(Issues)或分享想法!
304
-
305
- ---
306
-
307
- ## 🚀 快速入門總覽
308
-
309
- | 任務 | 方法 |
310
- |------|------|
311
- | 安全處理 null/undefined | `Optional<T>` |
312
- | 建立資料流 | `from([...])`、`range()`、`fill()` |
313
- | 資料轉換 | `map()`、`filter()` |
314
- | 資料排序 | `sorted()`、`toOrdered()` |
315
- | 不排序(最快) | `toUnordered()` ✅ |
316
- | 分組 / 聚合 | `toMap()`、`group()`、`Collector` |
317
- | 統計分析 | `NumericStatistics`、`mean()`、`median()` 等 |
318
-
319
- ---
320
-
321
- ## 🔗 相關連結
406
+ ### 選擇統計分析(數值計算)
407
+ ```typescript
408
+ // 需要進行統計分析時
409
+ const stats = data
410
+ .toNumericStatistics(); // 數值統計
322
411
 
323
- - 📦 npm: https://www.npmjs.com/package/semantic-typescript
324
- - 🐙 GitHub: https://github.com/eloyhere/semantic-typescript
325
- - 📘 文件:請參考原始碼 / 類型定義
412
+ const bigIntStats = data
413
+ .toBigintStatistics(); // 大數統計
414
+ ```
326
415
 
327
- ---
416
+ [GitHub](https://github.com/eloyhere/semantic-typescript)
417
+ [NPMJS](https://www.npmjs.com/package/semantic-typescript)
328
418
 
329
- **享受在 TypeScript 中進行函數式、類型安全且可組合的資料處理吧!** 🚀
419
+ ## 注意事項
330
420
 
331
- ---
421
+ 1. **排序操作的影響**:在有序收集器中,`sorted()` 操作會覆蓋 `redirect`、`translate`、`shuffle`、`reverse` 的效果
422
+ 2. **效能考慮**:如果不需要順序保證,優先使用 `toUnoredered()` 獲得更好效能
423
+ 3. **記憶體使用**:排序操作需要 O(n) 的額外空間
424
+ 4. **實時數據**:Semantic 流適合處理實時數據,支援非同步數據源
332
425
 
333
- **請記住:**
334
- - `toUnordered()` → **不排序,最快**
335
- - 其他方法(如 `sorted()`、`toOrdered()`)→ **會進行排序**
426
+ 這個庫為 TypeScript 開發者提供了強大而靈活的流式處理能力,結合了函數式編程的優點和類型安全的保障。