semantic-typescript 0.0.6 → 0.0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/semantic.d.ts +8 -1
- package/dist/semantic.js +161 -9
- package/package.json +2 -2
- package/readme.cn.md +441 -247
- package/readme.de.md +434 -240
- package/readme.es.md +434 -240
- package/readme.fr.md +434 -240
- package/readme.jp.md +434 -240
- package/readme.kr.md +529 -0
- package/readme.md +434 -240
- package/readme.ru.md +529 -0
- package/readme.tw.md +441 -247
- package/readme.ko.md +0 -335
package/readme.jp.md
CHANGED
|
@@ -1,335 +1,529 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Semantic-TypeScript ストリーム処理フレームワーク
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
コレクション、ストリーム、シーケンスを扱うための関数的スタイルの構成要素を提供し、ソート、フィルタリング、グループ化、統計分析などをサポートします。
|
|
3
|
+
## はじめに
|
|
5
4
|
|
|
6
|
-
|
|
5
|
+
Semantic-TypeScriptは、JavaScriptのGeneratorFunction、Java Stream、およびMySQL Indexにインスパイアされたモダンなストリーム処理ライブラリです。コアの設計哲学は、データインデックスを通じた効率的なデータ処理パイプラインの構築に基づいており、フロントエンド開発に型安全で関数型スタイルのストリーミング操作体験を提供します。
|
|
7
6
|
|
|
8
|
-
|
|
7
|
+
従来の同期処理とは異なり、Semanticは非同期処理モデルを採用しています。データストリームを作成する際、終端データの受信タイミングは、アップストリームが`accept`および`interrupt`コールバック関数を呼び出すタイミングに完全に依存します。この設計により、ライブラリはリアルタイムデータストリーム、大規模データセット、非同期データソースをエレガントに扱うことができます。
|
|
9
8
|
|
|
10
|
-
##
|
|
9
|
+
## コア機能
|
|
11
10
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
- ✅ **イテレータとジェネレーター**ベースの設計 — 大規模・非同期データにも適応
|
|
11
|
+
| 機能 | 説明 | 利点 |
|
|
12
|
+
|------|------|------|
|
|
13
|
+
| **型安全ジェネリクス** | 完全なTypeScript型サポート | コンパイル時エラー検出、優れた開発体験 |
|
|
14
|
+
| **関数型プログラミング** | 不変データ構造と純粋関数 | 予測可能なコード、テストと保守が容易 |
|
|
15
|
+
| **遅延評価** | オンデマンド計算、パフォーマンス最適化 | 大規模データセット処理時の高いメモリ効率 |
|
|
16
|
+
| **非同期ストリーム処理** | ジェネレータベースの非同期データストリーム | リアルタイムデータとイベント駆動シナリオに適応 |
|
|
17
|
+
| **マルチパラダイムコレクター** | 順序付き、順序なし、統計的収集戦略 | 異なるシナリオに基づく最適な戦略選択 |
|
|
18
|
+
| **統計分析** | 組み込みの完全な統計計算関数 | 統合データ分析とレポート生成 |
|
|
21
19
|
|
|
22
|
-
|
|
20
|
+
## パフォーマンスに関する考慮事項
|
|
23
21
|
|
|
24
|
-
|
|
22
|
+
**重要な注意**: 以下のメソッドは、データを収集してソートするため、パフォーマンスを犠牲にして順序付きデータコレクションを生成します:
|
|
23
|
+
- `toOrdered()`
|
|
24
|
+
- `toWindow()`
|
|
25
|
+
- `toNumericStatistics()`
|
|
26
|
+
- `toBigIntStatistics()`
|
|
27
|
+
- `sorted()`
|
|
28
|
+
- `sorted(comparator)`
|
|
25
29
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
---
|
|
31
|
-
|
|
32
|
-
## 🧠 コア概念
|
|
33
|
-
|
|
34
|
-
### 1. `Optional<T>` – 安全な null 値処理
|
|
35
|
-
|
|
36
|
-
`null` または `undefined` になり得る値を格納するモナディックコンテナです。
|
|
30
|
+
特に重要な注意点: `sorted()`および`sorted(comparator)`は、以下のメソッドの結果を上書きします:
|
|
31
|
+
- `redirect(redirector)`
|
|
32
|
+
- `translate(translator)`
|
|
33
|
+
- `shuffle(mapper)`
|
|
37
34
|
|
|
38
|
-
|
|
35
|
+
## ファクトリメソッド
|
|
39
36
|
|
|
40
|
-
|
|
41
|
-
|----------|------|-----|
|
|
42
|
-
| `of(value)` | 値をラップ(nullish も可) | `Optional.of(null)` |
|
|
43
|
-
| `ofNullable(v)` | ラップ(nullish を許容) | `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()` |
|
|
37
|
+
### ストリーム作成ファクトリ
|
|
52
38
|
|
|
53
|
-
|
|
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)` |
|
|
54
48
|
|
|
49
|
+
**コード例補足:**
|
|
55
50
|
```typescript
|
|
56
|
-
import {
|
|
51
|
+
import { from, range, fill, empty } from 'semantic-typescript';
|
|
57
52
|
|
|
58
|
-
|
|
53
|
+
// 配列からストリーム作成
|
|
54
|
+
const numberStream = from([1, 2, 3, 4, 5]);
|
|
59
55
|
|
|
60
|
-
|
|
56
|
+
// 数値範囲ストリーム作成
|
|
57
|
+
const rangeStream = range(1, 10, 2); // 1, 3, 5, 7, 9
|
|
61
58
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
.map(v => v * 2)
|
|
65
|
-
.getOrDefault(0);
|
|
59
|
+
// 繰り返し要素で埋め立て
|
|
60
|
+
const filledStream = fill("hello", 3n); // "hello", "hello", "hello"
|
|
66
61
|
|
|
67
|
-
|
|
62
|
+
// 空のストリーム作成
|
|
63
|
+
const emptyStream = empty<number>();
|
|
68
64
|
```
|
|
69
65
|
|
|
70
|
-
|
|
66
|
+
### ユーティリティ関数ファクトリ
|
|
71
67
|
|
|
72
|
-
|
|
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)` → 乱数 |
|
|
73
74
|
|
|
74
|
-
|
|
75
|
+
**コード例補足:**
|
|
76
|
+
```typescript
|
|
77
|
+
import { validate, invalidate, useCompare, useRandom } from 'semantic-typescript';
|
|
75
78
|
|
|
76
|
-
|
|
79
|
+
// データ有効性検証
|
|
80
|
+
const data: string | null = "hello";
|
|
81
|
+
if (validate(data)) {
|
|
82
|
+
console.log(data.toUpperCase()); // validateがデータがnullでないことを保証するため安全な呼び出し
|
|
83
|
+
}
|
|
77
84
|
|
|
78
|
-
|
|
85
|
+
const nullData: string | null = null;
|
|
86
|
+
if (invalidate(nullData)) {
|
|
87
|
+
console.log("データが無効です"); // invalidateがnullを検出したため実行される
|
|
88
|
+
}
|
|
79
89
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
| `from(iterable)` | Array/Set/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)` |
|
|
90
|
+
// 値の比較
|
|
91
|
+
const comparison = useCompare("apple", "banana"); // -1
|
|
86
92
|
|
|
87
|
-
|
|
93
|
+
// 乱数生成
|
|
94
|
+
const randomNum = useRandom(42); // シード42に基づく乱数
|
|
95
|
+
```
|
|
88
96
|
|
|
89
|
-
|
|
90
|
-
|----------|------|-----|
|
|
91
|
-
| `map(fn)` | 各要素を変換 | `.map(x => x * 2)` |
|
|
92
|
-
| `filter(fn)` | 述語を満たす要素を保持 | `.filter(x => x > 10)` |
|
|
93
|
-
| `limit(n)` | 最初の N 要素に制限 | `.limit(5)` |
|
|
94
|
-
| `skip(n)` | 最初の N 要素をスキップ | `.skip(2)` |
|
|
95
|
-
| `distinct()` | 重複を除去(デフォルトで Set を使用) | `.distinct()` |
|
|
96
|
-
| `sorted()` | 要素をソート(自然順) | `.sorted()` |
|
|
97
|
-
| `sorted(comparator)` | カスタムソート | `.sorted((a, b) => a - b)` |
|
|
98
|
-
| `toOrdered()` | ソートして `OrderedCollectable` を返す | `.toOrdered()` |
|
|
99
|
-
| `toUnordered()` | **ソートなし** – 最速のコレクション | `.toUnordered()` ✅ |
|
|
100
|
-
| `collect(collector)` | コレクターで集約 | `.collect(Collector.full(...))` |
|
|
101
|
-
| `toArray()` | 配列に変換 | `.toArray()` |
|
|
102
|
-
| `toSet()` | Set に変換 | `.toSet()` |
|
|
103
|
-
| `toMap(keyFn, valFn)` | Map に変換 | `.toMap(x => x.id, x => x)` |
|
|
97
|
+
## コアクラス詳細
|
|
104
98
|
|
|
105
|
-
|
|
99
|
+
### Optional<T> - 安全なnull値処理
|
|
106
100
|
|
|
107
|
-
|
|
101
|
+
Optionalクラスは、nullまたはundefinedになる可能性のある値を安全に扱うための関数型アプローチを提供します。
|
|
108
102
|
|
|
109
|
-
|
|
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>` | null許容Optionalを作成 | O(1) |
|
|
114
|
+
| `static ofNonNull<T>(value: T)` | `Optional<T>` | non-null Optionalを作成 | O(1) |
|
|
110
115
|
|
|
116
|
+
**コード例補足:**
|
|
111
117
|
```typescript
|
|
112
|
-
|
|
113
|
-
```
|
|
118
|
+
import { Optional } from 'semantic-typescript';
|
|
114
119
|
|
|
115
|
-
|
|
116
|
-
|
|
120
|
+
// Optionalインスタンス作成
|
|
121
|
+
const optionalValue = Optional.ofNullable<string>(Math.random() > 0.5 ? "hello" : null);
|
|
117
122
|
|
|
118
|
-
|
|
123
|
+
// チェーン操作
|
|
124
|
+
const result = optionalValue
|
|
125
|
+
.filter(val => val.length > 3) // 長さが3より大きい値をフィルタリング
|
|
126
|
+
.map(val => val.toUpperCase()) // 大文字に変換
|
|
127
|
+
.getOrDefault("default"); // 値またはデフォルト値を取得
|
|
119
128
|
|
|
120
|
-
|
|
129
|
+
console.log(result); // "HELLO" または "default"
|
|
121
130
|
|
|
122
|
-
|
|
131
|
+
// 安全な操作
|
|
132
|
+
optionalValue.ifPresent(val => {
|
|
133
|
+
console.log(`値が存在します: ${val}`);
|
|
134
|
+
});
|
|
123
135
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
136
|
+
// ステータスチェック
|
|
137
|
+
if (optionalValue.isPresent()) {
|
|
138
|
+
console.log("値があります");
|
|
139
|
+
} else if (optionalValue.isEmpty()) {
|
|
140
|
+
console.log("空です");
|
|
141
|
+
}
|
|
128
142
|
```
|
|
129
143
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
144
|
+
### Semantic<E> - 遅延データストリーム
|
|
145
|
+
|
|
146
|
+
Semanticは、豊富なストリーム演算子を提供するコアのストリーム処理クラスです。
|
|
147
|
+
|
|
148
|
+
#### ストリーム変換操作
|
|
149
|
+
|
|
150
|
+
| メソッド | 戻り値の型 | 説明 | パフォーマンス影響 |
|
|
151
|
+
|------|----------|------|----------|
|
|
152
|
+
| `concat(other: Semantic<E>)` | `Semantic<E>` | 2つのストリームを連結 | 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';
|
|
135
175
|
|
|
136
|
-
|
|
176
|
+
const stream = from([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
|
|
137
177
|
|
|
138
|
-
|
|
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(`インデックス${index}の要素${val}`)); // 要素を閲覧
|
|
139
185
|
|
|
140
|
-
|
|
141
|
-
Collector.full(identity, accumulator, finisher)
|
|
142
|
-
Collector.shortable(identity, interruptor, accumulator, finisher)
|
|
186
|
+
// 注: ストリームはまだ実行されていない、終端操作のためにCollectableへの変換が必要
|
|
143
187
|
```
|
|
144
188
|
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
---
|
|
189
|
+
#### ストリーム終端操作
|
|
148
190
|
|
|
149
|
-
|
|
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>` | カスタムソート | リダイレクト結果を上書き |
|
|
150
200
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
- `UnorderedCollectable<E>` – ソートなし、最速
|
|
155
|
-
- `WindowCollectable<E>` – スライディングウィンドウ
|
|
156
|
-
- `Statistics<E, D>` – 統計集約
|
|
201
|
+
**コード例補足:**
|
|
202
|
+
```typescript
|
|
203
|
+
import { from } from 'semantic-typescript';
|
|
157
204
|
|
|
158
|
-
|
|
205
|
+
const semanticStream = from([5, 2, 8, 1, 9, 3, 7, 4, 6]);
|
|
159
206
|
|
|
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)` |
|
|
207
|
+
// 順序付きコレクションに変換(パフォーマンス低い)
|
|
208
|
+
const ordered = semanticStream.toOrdered();
|
|
170
209
|
|
|
171
|
-
|
|
210
|
+
// 順序なしコレクションに変換(最速)
|
|
211
|
+
const unordered = semanticStream.toUnordered();
|
|
172
212
|
|
|
173
|
-
|
|
213
|
+
// 自然順ソート
|
|
214
|
+
const sortedNatural = semanticStream.sorted();
|
|
174
215
|
|
|
175
|
-
|
|
216
|
+
// カスタムソート
|
|
217
|
+
const sortedCustom = semanticStream.sorted((a, b) => b - a); // 降順ソート
|
|
176
218
|
|
|
177
|
-
|
|
219
|
+
// 統計オブジェクトに変換
|
|
220
|
+
const stats = semanticStream.toNumericStatistics();
|
|
178
221
|
|
|
179
|
-
|
|
180
|
-
const sorted = new OrderedCollectable(stream);
|
|
181
|
-
const customSorted = new OrderedCollectable(stream, (a, b) => b - a);
|
|
222
|
+
// 注: 上記メソッドはSemanticインスタンスを通じて呼び出し、Collectableを取得してから終端メソッドを使用する必要がある
|
|
182
223
|
```
|
|
183
224
|
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
---
|
|
225
|
+
### Collector<E, A, R> - データコレクター
|
|
187
226
|
|
|
188
|
-
|
|
227
|
+
コレクターは、ストリームデータを特定の構造に集約するために使用されます。
|
|
189
228
|
|
|
190
|
-
|
|
229
|
+
| メソッド | 説明 | 使用シナリオ |
|
|
230
|
+
|------|------|----------|
|
|
231
|
+
| `collect(generator)` | データ収集を実行 | ストリーム終端操作 |
|
|
232
|
+
| `static full(identity, accumulator, finisher)` | 完全なコレクターを作成 | 完全な処理が必要 |
|
|
233
|
+
| `static shortable(identity, interruptor, accumulator, finisher)` | 中断可能なコレクターを作成 | 早期終了する可能性あり |
|
|
191
234
|
|
|
235
|
+
**コード例補足:**
|
|
192
236
|
```typescript
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
237
|
+
import { Collector } from 'semantic-typescript';
|
|
238
|
+
|
|
239
|
+
// カスタムコレクター作成
|
|
240
|
+
const sumCollector = Collector.full(
|
|
241
|
+
() => 0, // 初期値
|
|
242
|
+
(acc, value) => acc + value, // アキュムレータ
|
|
243
|
+
result => result // フィニッシャー関数
|
|
244
|
+
);
|
|
245
|
+
|
|
246
|
+
// コレクター使用(SemanticからCollectableへの変換が最初に必要)
|
|
247
|
+
const numbers = from([1, 2, 3, 4, 5]);
|
|
248
|
+
const sum = numbers.toUnordered().collect(sumCollector); // 15
|
|
196
249
|
```
|
|
197
250
|
|
|
198
|
-
|
|
199
|
-
✅ **順序が無関係な場合の最高パフォーマンス**
|
|
200
|
-
|
|
201
|
-
---
|
|
251
|
+
### Collectable<E> - 収集可能データ抽象クラス
|
|
202
252
|
|
|
203
|
-
|
|
253
|
+
豊富なデータ集約および変換メソッドを提供します。**注: 最初にSemanticインスタンスを通じてsorted()、toOrdered()などを呼び出してCollectableインスタンスを取得してから、以下のメソッドを使用する必要があります。**
|
|
204
254
|
|
|
205
|
-
|
|
255
|
+
#### データクエリ操作
|
|
206
256
|
|
|
207
|
-
|
|
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()` |
|
|
208
266
|
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
##### 主な統計メソッド:
|
|
267
|
+
**コード例補足:**
|
|
268
|
+
```typescript
|
|
269
|
+
import { from } from 'semantic-typescript';
|
|
213
270
|
|
|
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()` | 頻度マップ | `.frequency()` |
|
|
271
|
+
const numbers = from([1, 2, 3, 4, 5]);
|
|
227
272
|
|
|
228
|
-
|
|
273
|
+
// 終端メソッドを使用する前にCollectableに変換する必要がある
|
|
274
|
+
const collectable = numbers.toUnordered();
|
|
229
275
|
|
|
230
|
-
|
|
276
|
+
// データクエリ操作
|
|
277
|
+
const hasEven = collectable.anyMatch(x => x % 2 === 0); // true
|
|
278
|
+
const allPositive = collectable.allMatch(x => x > 0); // true
|
|
279
|
+
const count = collectable.count(); // 5n
|
|
280
|
+
const isEmpty = collectable.isEmpty(); // false
|
|
281
|
+
const firstElement = collectable.findFirst(); // Optional.of(1)
|
|
282
|
+
const anyElement = collectable.findAny(); // 任意の要素
|
|
283
|
+
```
|
|
231
284
|
|
|
285
|
+
#### データ集約操作
|
|
286
|
+
|
|
287
|
+
| メソッド | 戻り値の型 | 説明 | 計算量 |
|
|
288
|
+
|------|----------|------|--------|
|
|
289
|
+
| `group(classifier)` | `Map<K, E[]>` | 分類子でグループ化 | O(n) |
|
|
290
|
+
| `groupBy(keyExtractor, valueExtractor)` | `Map<K, V[]>` | キー値抽出器でグループ化 | O(n) |
|
|
291
|
+
| `join()` | `string` | 文字列として結合 | O(n) |
|
|
292
|
+
| `join(delimiter)` | `string` | 区切り文字で結合 | O(n) |
|
|
293
|
+
| `partition(count)` | `E[][]` | カウントで分割 | O(n) |
|
|
294
|
+
| `partitionBy(classifier)` | `E[][]` | 分類子で分割 | O(n) |
|
|
295
|
+
| `reduce(accumulator)` | `Optional<E>` | 縮約操作 | O(n) |
|
|
296
|
+
| `reduce(identity, accumulator)` | `E` | 識別子付き縮約 | O(n) |
|
|
297
|
+
| `toArray()` | `E[]` | 配列に変換 | O(n) |
|
|
298
|
+
| `toMap(keyExtractor, valueExtractor)` | `Map<K, V>` | Mapに変換 | O(n) |
|
|
299
|
+
| `toSet()` | `Set<E>` | Setに変換 | O(n) |
|
|
300
|
+
|
|
301
|
+
**コード例補足:**
|
|
232
302
|
```typescript
|
|
233
|
-
import { from
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
//
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
303
|
+
import { from } from 'semantic-typescript';
|
|
304
|
+
|
|
305
|
+
const people = from([
|
|
306
|
+
{ name: "Alice", age: 25, city: "New York" },
|
|
307
|
+
{ name: "Bob", age: 30, city: "London" },
|
|
308
|
+
{ name: "Charlie", age: 25, city: "New York" }
|
|
309
|
+
]);
|
|
310
|
+
|
|
311
|
+
// 集約操作を使用する前にCollectableに変換する必要がある
|
|
312
|
+
const collectable = people.toUnordered();
|
|
313
|
+
|
|
314
|
+
// グループ化操作
|
|
315
|
+
const byCity = collectable.group(person => person.city);
|
|
316
|
+
// Map { "New York" => [{name: "Alice", ...}, {name: "Charlie", ...}], "London" => [{name: "Bob", ...}] }
|
|
317
|
+
|
|
318
|
+
const byAge = collectable.groupBy(
|
|
319
|
+
person => person.age,
|
|
320
|
+
person => person.name
|
|
321
|
+
);
|
|
322
|
+
// Map { 25 => ["Alice", "Charlie"], 30 => ["Bob"] }
|
|
323
|
+
|
|
324
|
+
// コレクションに変換
|
|
325
|
+
const array = collectable.toArray(); // 元の配列
|
|
326
|
+
const set = collectable.toSet(); // Setコレクション
|
|
327
|
+
const map = collectable.toMap(
|
|
328
|
+
person => person.name,
|
|
329
|
+
person => person.age
|
|
330
|
+
); // Map { "Alice" => 25, "Bob" => 30, "Charlie" => 25 }
|
|
331
|
+
|
|
332
|
+
// 縮約操作
|
|
333
|
+
const totalAge = collectable.reduce(0, (acc, person) => acc + person.age); // 80
|
|
334
|
+
const oldest = collectable.reduce((a, b) => a.age > b.age ? a : b); // Optional.of({name: "Bob", age: 30, ...})
|
|
253
335
|
```
|
|
254
336
|
|
|
255
|
-
|
|
337
|
+
### 特定のコレクター実装
|
|
256
338
|
|
|
257
|
-
|
|
339
|
+
#### UnorderedCollectable<E>
|
|
340
|
+
- **特性**: 最速のコレクター、ソートなし
|
|
341
|
+
- **使用シナリオ**: 順序が重要でない、最大のパフォーマンスが望まれる場合
|
|
342
|
+
- **メソッド**: すべてのCollectableメソッドを継承
|
|
258
343
|
|
|
259
|
-
|
|
344
|
+
#### OrderedCollectable<E>
|
|
345
|
+
- **特性**: 要素の順序を保証、パフォーマンスは低い
|
|
346
|
+
- **使用シナリオ**: ソートされた結果が必要な場合
|
|
347
|
+
- **特殊メソッド**: すべてのメソッドを継承、内部ソート状態を維持
|
|
260
348
|
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
| `useCompare(a, b)` | 汎用比較関数 |
|
|
268
|
-
| `useRandom(x)` | 疑似乱数ジェネレーター(楽しい) |
|
|
349
|
+
#### WindowCollectable<E>
|
|
350
|
+
- **特性**: スライディングウィンドウ操作をサポート
|
|
351
|
+
- **使用シナリオ**: 時系列データ分析
|
|
352
|
+
- **特殊メソッド**:
|
|
353
|
+
- `slide(size, step)` - スライディングウィンドウ
|
|
354
|
+
- `tumble(size)` - タンブリングウィンドウ
|
|
269
355
|
|
|
270
|
-
|
|
356
|
+
**コード例補足:**
|
|
357
|
+
```typescript
|
|
358
|
+
import { from } from 'semantic-typescript';
|
|
271
359
|
|
|
272
|
-
|
|
360
|
+
const data = from([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
|
|
273
361
|
|
|
274
|
-
|
|
362
|
+
// 順序なしコレクター(最速)
|
|
363
|
+
const unordered = data.toUnordered();
|
|
364
|
+
const unorderedArray = unordered.toArray(); // 元の順序を維持する可能性あり [1, 2, 3, ...]
|
|
275
365
|
|
|
276
|
-
|
|
277
|
-
const
|
|
278
|
-
|
|
279
|
-
accept(i, BigInt(i));
|
|
280
|
-
if (i === 5) interrupt(i);
|
|
281
|
-
}
|
|
282
|
-
};
|
|
283
|
-
|
|
284
|
-
const s = new Semantic(gen);
|
|
285
|
-
```
|
|
366
|
+
// 順序付きコレクター
|
|
367
|
+
const ordered = data.toOrdered();
|
|
368
|
+
const orderedArray = ordered.toArray(); // ソートが保証される [1, 2, 3, ...]
|
|
286
369
|
|
|
287
|
-
|
|
370
|
+
// ウィンドウコレクター
|
|
371
|
+
const windowed = data.toWindow();
|
|
372
|
+
const slidingWindows = windowed.slide(3n, 2n); // ウィンドウサイズ3、ステップ2
|
|
373
|
+
// ウィンドウ1: [1, 2, 3], ウィンドウ2: [3, 4, 5], ウィンドウ3: [5, 6, 7], ...
|
|
288
374
|
|
|
289
|
-
|
|
290
|
-
|
|
375
|
+
const tumblingWindows = windowed.tumble(4n); // タンブリングウィンドウサイズ4
|
|
376
|
+
// ウィンドウ1: [1, 2, 3, 4], ウィンドウ2: [5, 6, 7, 8], ...
|
|
291
377
|
```
|
|
292
378
|
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
379
|
+
### Statistics<E, D> - 統計分析
|
|
380
|
+
|
|
381
|
+
統計分析の基底クラスで、豊富な統計計算メソッドを提供します。**注: 最初にSemanticインスタンスを通じてtoNumericStatistics()またはtoBigIntStatistics()を呼び出してStatisticsインスタンスを取得してから、以下のメソッドを使用する必要があります。**
|
|
382
|
+
|
|
383
|
+
#### 統計計算操作
|
|
384
|
+
|
|
385
|
+
| メソッド | 戻り値の型 | 説明 | アルゴリズム計算量 |
|
|
386
|
+
|------|----------|------|------------|
|
|
387
|
+
| `maximum()` | `Optional<E>` | 最大値 | O(n) |
|
|
388
|
+
| `minimum()` | `Optional<E>` | 最小値 | O(n) |
|
|
389
|
+
| `range()` | `D` | 範囲(最大-最小) | O(n) |
|
|
390
|
+
| `variance()` | `D` | 分散 | O(n) |
|
|
391
|
+
| `standardDeviation()` | `D` | 標準偏差 | O(n) |
|
|
392
|
+
| `mean()` | `D` | 平均値 | O(n) |
|
|
393
|
+
| `median()` | `D` | 中央値 | O(n log n) |
|
|
394
|
+
| `mode()` | `D` | 最頻値 | O(n) |
|
|
395
|
+
| `frequency()` | `Map<D, bigint>` | 度数分布 | O(n) |
|
|
396
|
+
| `summate()` | `D` | 合計 | O(n) |
|
|
397
|
+
| `quantile(quantile)` | `D` | 分位数 | O(n log n) |
|
|
398
|
+
| `interquartileRange()` | `D` | 四分位範囲 | O(n log n) |
|
|
399
|
+
| `skewness()` | `D` | 歪度 | O(n) |
|
|
400
|
+
| `kurtosis()` | `D` | 尖度 | O(n) |
|
|
401
|
+
|
|
402
|
+
**コード例補足:**
|
|
403
|
+
```typescript
|
|
404
|
+
import { from } from 'semantic-typescript';
|
|
405
|
+
|
|
406
|
+
const numbers = from([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
|
|
407
|
+
|
|
408
|
+
// 統計メソッドを使用する前に統計オブジェクトに変換する必要がある
|
|
409
|
+
const stats = numbers.toNumericStatistics();
|
|
410
|
+
|
|
411
|
+
// 基本統計
|
|
412
|
+
const count = stats.count(); // 10n
|
|
413
|
+
const max = stats.maximum(); // Optional.of(10)
|
|
414
|
+
const min = stats.minimum(); // Optional.of(1)
|
|
415
|
+
const range = stats.range(); // 9
|
|
416
|
+
const mean = stats.mean(); // 5.5
|
|
417
|
+
const median = stats.median(); // 5.5
|
|
418
|
+
const sum = stats.summate(); // 55
|
|
419
|
+
|
|
420
|
+
// 高度な統計
|
|
421
|
+
const variance = stats.variance(); // 8.25
|
|
422
|
+
const stdDev = stats.standardDeviation(); // 2.872
|
|
423
|
+
const mode = stats.mode(); // 任意の値(すべて1回ずつ出現するため)
|
|
424
|
+
const q1 = stats.quantile(0.25); // 3.25
|
|
425
|
+
const q3 = stats.quantile(0.75); // 7.75
|
|
426
|
+
const iqr = stats.interquartileRange(); // 4.5
|
|
427
|
+
|
|
428
|
+
// 度数分布
|
|
429
|
+
const freq = stats.frequency(); // Map {1 => 1n, 2 => 1n, ...}
|
|
430
|
+
```
|
|
298
431
|
|
|
299
|
-
|
|
432
|
+
#### 特定の統計実装クラス
|
|
300
433
|
|
|
301
|
-
|
|
434
|
+
**NumericStatistics<E>**
|
|
435
|
+
- number型の統計分析を処理
|
|
436
|
+
- すべての統計計算はnumber型を返す
|
|
302
437
|
|
|
303
|
-
|
|
438
|
+
**BigIntStatistics<E>**
|
|
439
|
+
- bigint型の統計分析を処理
|
|
440
|
+
- すべての統計計算はbigint型を返す
|
|
304
441
|
|
|
305
|
-
|
|
442
|
+
**コード例補足:**
|
|
443
|
+
```typescript
|
|
444
|
+
import { from } from 'semantic-typescript';
|
|
306
445
|
|
|
307
|
-
|
|
446
|
+
// 数値統計
|
|
447
|
+
const numberData = from([10, 20, 30, 40, 50]);
|
|
448
|
+
const numericStats = numberData.toNumericStatistics();
|
|
308
449
|
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
| null を安全に処理 | `Optional<T>` |
|
|
312
|
-
| ストリームを作成 | `from([...])`、`range()`、`fill()` |
|
|
313
|
-
| データを変換 | `map()`、`filter()` |
|
|
314
|
-
| データをソート | `sorted()`、`toOrdered()` |
|
|
315
|
-
| ソートなし(最速) | `toUnordered()` ✅ |
|
|
316
|
-
| グループ化/集約 | `toMap()`、`group()`、`Collector` |
|
|
317
|
-
| 統計 | `NumericStatistics`、`mean()`、`median()` など |
|
|
450
|
+
console.log(numericStats.mean()); // 30
|
|
451
|
+
console.log(numericStats.summate()); // 150
|
|
318
452
|
|
|
319
|
-
|
|
453
|
+
// ビッグ整数統計
|
|
454
|
+
const bigintData = from([100n, 200n, 300n, 400n, 500n]);
|
|
455
|
+
const bigintStats = bigintData.toBigIntStatistics();
|
|
320
456
|
|
|
321
|
-
|
|
457
|
+
console.log(bigintStats.mean()); // 300n
|
|
458
|
+
console.log(bigintStats.summate()); // 1500n
|
|
322
459
|
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
460
|
+
// マッパー関数を使用した統計
|
|
461
|
+
const objectData = from([
|
|
462
|
+
{ value: 15 },
|
|
463
|
+
{ value: 25 },
|
|
464
|
+
{ value: 35 },
|
|
465
|
+
{ value: 45 }
|
|
466
|
+
]);
|
|
326
467
|
|
|
327
|
-
|
|
468
|
+
const objectStats = objectData.toNumericStatistics();
|
|
469
|
+
const meanWithMapper = objectStats.mean(obj => obj.value); // 30
|
|
470
|
+
const sumWithMapper = objectStats.summate(obj => obj.value); // 120
|
|
471
|
+
```
|
|
328
472
|
|
|
329
|
-
|
|
473
|
+
## 完全な使用例
|
|
330
474
|
|
|
331
|
-
|
|
475
|
+
```typescript
|
|
476
|
+
import { from, validate, invalidate } from 'semantic-typescript';
|
|
477
|
+
|
|
478
|
+
// 1. データストリーム作成
|
|
479
|
+
const rawData = [5, 2, 8, 1, null, 9, 3, undefined, 7, 4, 6];
|
|
480
|
+
const semanticStream = from(rawData);
|
|
481
|
+
|
|
482
|
+
// 2. ストリーム処理パイプライン
|
|
483
|
+
const processedStream = semanticStream
|
|
484
|
+
.filter(val => validate(val)) // nullとundefinedをフィルタリング
|
|
485
|
+
.map(val => val! * 2) // 各値を2倍(!を使用、validateが空でないことを保証するため)
|
|
486
|
+
.distinct(); // 重複を削除
|
|
487
|
+
|
|
488
|
+
// 3. Collectableに変換して終端操作を使用
|
|
489
|
+
const collectable = processedStream.toUnordered();
|
|
490
|
+
|
|
491
|
+
// 4. データ検証と使用
|
|
492
|
+
if (!collectable.isEmpty()) {
|
|
493
|
+
const results = collectable
|
|
494
|
+
.filter(x => x > 5) // 再度フィルタリング
|
|
495
|
+
.toArray(); // 配列に変換
|
|
496
|
+
|
|
497
|
+
console.log("処理結果:", results); // [16, 18, 14, 8, 12]
|
|
498
|
+
|
|
499
|
+
// 統計情報
|
|
500
|
+
const stats = processedStream.toNumericStatistics();
|
|
501
|
+
console.log("平均値:", stats.mean()); // 11.2
|
|
502
|
+
console.log("合計:", stats.summate()); // 56
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
// 5. 潜在的に無効なデータの処理
|
|
506
|
+
const potentiallyInvalidData: Array<number | null> = [1, null, 3, 4, null];
|
|
507
|
+
const validData = potentiallyInvalidData.filter(validate);
|
|
508
|
+
const invalidData = potentiallyInvalidData.filter(invalidate);
|
|
509
|
+
|
|
510
|
+
console.log("有効なデータ:", validData); // [1, 3, 4]
|
|
511
|
+
console.log("無効なデータ:", invalidData); // [null, null]
|
|
512
|
+
```
|
|
332
513
|
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
514
|
+
## 重要な使用ルールのまとめ
|
|
515
|
+
|
|
516
|
+
1. **ストリーム作成**: `from()`、`range()`、`fill()`などのファクトリメソッドを使用してSemanticインスタンスを作成
|
|
517
|
+
2. **ストリーム変換**: Semanticインスタンスで`map()`、`filter()`、`distinct()`などのメソッドを呼び出し
|
|
518
|
+
3. **Collectableへの変換**: Semanticインスタンスを通じて以下のいずれかのメソッドを呼び出す必要があります:
|
|
519
|
+
- `toOrdered()` - 順序付きコレクター
|
|
520
|
+
- `toUnordered()` - 順序なしコレクター(最速)
|
|
521
|
+
- `toWindow()` - ウィンドウコレクター
|
|
522
|
+
- `toNumericStatistics()` - 数値統計
|
|
523
|
+
- `toBigIntStatistics()` - ビッグ整数統計
|
|
524
|
+
- `sorted()` - 自然順ソート
|
|
525
|
+
- `sorted(comparator)` - カスタムソート
|
|
526
|
+
4. **終端操作**: Collectableインスタンスで`toArray()`、`count()`、`summate()`などの終端メソッドを呼び出し
|
|
527
|
+
5. **データ検証**: `validate()`を使用してデータがnull/undefinedでないことを保証、`invalidate()`を使用して無効なデータをチェック
|
|
528
|
+
|
|
529
|
+
この設計は、型安全性とパフォーマンス最適化を確保しながら、豊富なストリーム処理機能を提供します。
|