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/readme.de.md CHANGED
@@ -1,335 +1,529 @@
1
- # 📘 semantic-typescript
1
+ # Semantic-TypeScript Stream Processing Framework
2
2
 
3
- Eine leistungsstarke, typsichere Utility-Bibliothek für die **semantische Datenverarbeitung** in TypeScript.
4
- Sie bietet komponierbare, funktional-programmierende Konstrukte zur Arbeit mit Collections, Streams und Sequenzen – inklusive Unterstützung für Sortieren, Filtern, Gruppieren, Statistik und mehr.
3
+ ## Einführung
5
4
 
6
- Ob Sie **sortierte oder unsortierte Daten** verarbeiten, **statistische Analysen** durchführen oder einfach nur **operationen flüssig verketten** möchten diese Bibliothek deckt Ihr Bedürfnis ab.
5
+ Semantic-TypeScript ist eine moderne Stream-Processing-Bibliothek, inspiriert von JavaScript GeneratorFunction, Java Stream und MySQL Index. Die Kern-Designphilosophie basiert auf dem Aufbau effizienter Datenverarbeitungspipelines durch Datenindizierung und bietet eine typsichere, funktionale Stream-Operation-Erfahrung für die Frontend-Entwicklung.
7
6
 
8
- ---
7
+ Im Gegensatz zur traditionellen synchronen Verarbeitung verwendet Semantic ein asynchrones Verarbeitungsmodell. Beim Erstellen von Datenströmen hängt der Zeitpunkt des terminalen Datenempfangs vollständig davon ab, wann der Upstream die `accept`- und `interrupt`-Callback-Funktionen aufruft. Dieses Design ermöglicht es der Bibliothek, Echtzeit-Datenströme, große Datensätze und asynchrone Datenquellen elegant zu verarbeiten.
9
8
 
10
- ## 🧩 Merkmale
9
+ ## Kernfunktionen
11
10
 
12
- - Vollständig **typsichere Generics**
13
- - ✅ **Funktionale Programmierung** (z. B. map, filter, reduce)
14
- - **Semantische Datenströme** (`Semantic<E>`) für **Lazy Evaluation**
15
- - **Collector** zum Umwandeln von Streams in konkrete Datenstrukturen
16
- - **Sortierte und unsortierte Collectables** `toUnordered()` ist **am schnellsten (kein Sortieren**
17
- - **Sortieren** über `sorted()`, `toOrdered()`, Vergleichsfunktionen
18
- - **Statistische Analyse** (`Statistics`, `NumericStatistics`, `BigIntStatistics`)
19
- - **Optional<T>** Monade für sicheres Arbeiten mit potenziell `null` oder `undefined`
20
- - ✅ **Iteratoren & Generatoren** basiertes Design – ideal auch für große oder asynchrone Daten
11
+ | Funktion | Beschreibung | Vorteil |
12
+ |------|------|------|
13
+ | **Typsichere Generics** | Vollständige TypeScript-Typunterstützung | Fehlererkennung zur Kompilierzeit, bessere Entwicklungserfahrung |
14
+ | **Funktionale Programmierung** | Unveränderliche Datenstrukturen und reine Funktionen | Vorhersehbarerer Code, einfachere Tests und Wartung |
15
+ | **Lazy Evaluation** | Bedarfsgerechte Berechnung, Leistungsoptimierung | Hohe Speichereffizienz bei der Verarbeitung großer Datensätze |
16
+ | **Asynchrone Stream-Verarbeitung** | Generator-basierte asynchrone Datenströme | Geeignet für Echtzeitdaten und ereignisgesteuerte Szenarien |
17
+ | **Multi-Paradigma-Sammler** | Geordnete, ungeordnete, statistische Sammlungsstrategien | Optimale Strategiewahl basierend auf verschiedenen Szenarien |
18
+ | **Statistische Analyse** | Eingebaute vollständige statistische Berechnungsfunktionen | Integrierte Datenanalyse und Berichterstellungsgenerierung |
21
19
 
22
- ---
20
+ ## Leistungsüberlegungen
23
21
 
24
- ## 📦 Installation
22
+ **Wichtiger Hinweis**: Die folgenden Methoden opfern Leistung, um Daten zu sammeln und zu sortieren, was zu geordneten Datensammlungen führt:
23
+ - `toOrdered()`
24
+ - `toWindow()`
25
+ - `toNumericStatistics()`
26
+ - `toBigIntStatistics()`
27
+ - `sorted()`
28
+ - `sorted(comparator)`
25
29
 
26
- ```bash
27
- npm install semantic-typescript
28
- ```
29
-
30
- ---
31
-
32
- ## 🧠 Kernkonzepte
33
-
34
- ### 1. `Optional<T>` – Sicheres Arbeiten mit Nullable-Werten
35
-
36
- Ein monadisches Container-Objekt für Werte, die `null` oder `undefined` sein können.
30
+ Besonders wichtig zu beachten: `sorted()` und `sorted(comparator)` überschreiben die Ergebnisse der folgenden Methoden:
31
+ - `redirect(redirector)`
32
+ - `translate(translator)`
33
+ - `shuffle(mapper)`
37
34
 
38
- #### Methoden:
35
+ ## Factory-Methoden
39
36
 
40
- | Methode | Beschreibung | Beispiel |
41
- |--------|-------------|---------|
42
- | `of(value)` | Wert einpacken (kann null/undefined sein) | `Optional.of(null)` |
43
- | `ofNullable(v)` | Einpacken, null/undefined erlaubt | `Optional.ofNullable(someVar)` |
44
- | `ofNonNull(v)` | Einpacken, bei null/undefined wird eine Exception geworfen | `Optional.ofNonNull(5)` |
45
- | `get()` | Wert auslesen (bei leerem Optional: Exception) | `opt.get()` |
46
- | `getOrDefault(d)` | Wert auslesen oder Standardwert verwenden | `opt.getOrDefault(0)` |
47
- | `ifPresent(fn)` | Side-Effect ausführen, wenn Wert vorhanden | `opt.ifPresent(x => console.log(x))` |
48
- | `map(fn)` | Wert transformieren (wenn vorhanden) | `opt.map(x => x + 1)` |
49
- | `filter(fn)` | Nur Werte behalten, die den Prädikat erfüllen | `opt.filter(x => x > 0)` |
50
- | `isEmpty()` | Prüfen, ob das Optional leer ist | `opt.isEmpty()` |
51
- | `isPresent()` | Prüfen, ob ein Wert vorhanden ist | `opt.isPresent()` |
37
+ ### Stream-Erstellungs-Factories
52
38
 
53
- #### Beispiel:
39
+ | Methode | Signatur | Beschreibung | Beispiel |
40
+ |------|------|------|------|
41
+ | `blob` | `(blob: Blob, chunk?: bigint) => Semantic<Uint8Array>` | Konvertiere Blob in Byte-Stream | `blob(fileBlob, 1024n)` |
42
+ | `empty` | `<E>() => Semantic<E>` | Erstelle leeren Stream | `empty<number>()` |
43
+ | `fill` | `<E>(element: E, count: bigint) => Semantic<E>` | Fülle mit angegebener Anzahl an Elementen | `fill("hallo", 5n)` |
44
+ | `from` | `<E>(iterable: Iterable<E>) => Semantic<E>` | Erstelle Stream aus iterierbarem Objekt | `from([1, 2, 3])` |
45
+ | `range` | `<N extends number\|bigint>(start: N, end: N, step?: N) => Semantic<N>` | Erstelle numerischen Bereichs-Stream | `range(1, 10, 2)` |
46
+ | `iterate` | `<E>(generator: Generator<E>) => Semantic<E>` | Erstelle Stream aus Generator-Funktion | `iterate(myGenerator)` |
47
+ | `websocket` | `(websocket: WebSocket) => Semantic<MessageEvent>` | Erstelle Ereignis-Stream aus WebSocket | `websocket(socket)` |
54
48
 
49
+ **Code-Beispiel-Ergänzung:**
55
50
  ```typescript
56
- import { Optional } from 'semantic-typescript';
51
+ import { from, range, fill, empty } from 'semantic-typescript';
57
52
 
58
- const value: number | null = Math.random() > 0.5 ? 10 : null;
53
+ // Erstelle Stream aus Array
54
+ const numberStream = from([1, 2, 3, 4, 5]);
59
55
 
60
- const opt = Optional.ofNullable(value);
56
+ // Erstelle numerischen Bereichs-Stream
57
+ const rangeStream = range(1, 10, 2); // 1, 3, 5, 7, 9
61
58
 
62
- const result = opt
63
- .filter(v => v > 5)
64
- .map(v => v * 2)
65
- .getOrDefault(0);
59
+ // Fülle mit wiederholten Elementen
60
+ const filledStream = fill("hallo", 3n); // "hallo", "hallo", "hallo"
66
61
 
67
- console.log(result); // 20 oder 0
62
+ // Erstelle leeren Stream
63
+ const emptyStream = empty<number>();
68
64
  ```
69
65
 
70
- ---
66
+ ### Hilfsfunktions-Factories
71
67
 
72
- ### 2. `Semantic<E>` Lazy Datenstrom
68
+ | Methode | Signatur | Beschreibung | Beispiel |
69
+ |------|------|------|------|
70
+ | `validate` | `<T>(t: MaybeInvalid<T>) => t is T` | Validiere ob Wert gültig ist | `validate(null)` → `false` |
71
+ | `invalidate` | `<T>(t: MaybeInvalid<T>) => t is null\|undefined` | Validiere ob Wert ungültig ist | `invalidate(0)` → `false` |
72
+ | `useCompare` | `<T>(t1: T, t2: T) => number` | Generische Vergleichsfunktion | `useCompare("a", "b")` → `-1` |
73
+ | `useRandom` | `<T = number\|bigint>(index: T) => T` | Pseudozufallszahlengenerator | `useRandom(5)` → Zufallszahl |
73
74
 
74
- Ein **Lazy, komponierbarer Sequence-Typ**. Ähnlich wie Java Streams oder Kotlin Sequences.
75
+ **Code-Beispiel-Ergänzung:**
76
+ ```typescript
77
+ import { validate, invalidate, useCompare, useRandom } from 'semantic-typescript';
75
78
 
76
- Erstellen Sie einen `Semantic`-Datenstrom mit Helfern wie `from()`, `range()`, `iterate()` oder `fill()`.
79
+ // Validiere Datenvalidität
80
+ const data: string | null = "hallo";
81
+ if (validate(data)) {
82
+ console.log(data.toUpperCase()); // Sichere Aufruf, da validate sicherstellt, dass Daten nicht null sind
83
+ }
77
84
 
78
- #### Erzeugungsmethoden:
85
+ const nullData: string | null = null;
86
+ if (invalidate(nullData)) {
87
+ console.log("Daten ungültig"); // Wird ausgeführt, da invalidate null erkannt hat
88
+ }
79
89
 
80
- | Funktion | Beschreibung | Beispiel |
81
- |----------|-------------|---------|
82
- | `from(iterable)` | Aus Array/Set/Iterable erstellen | `from([1, 2, 3])` |
83
- | `range(start, end, step?)` | Zahlenbereich erzeugen | `range(0, 5)` → 0,1,2,3,4 |
84
- | `fill(element, count)` | Einen Wert N-mal wiederholen | `fill('a', 3n)` |
85
- | `iterate(gen)` | Benutzerdefinierten Generator verwenden | `iterate(genFn)` |
90
+ // Vergleiche Werte
91
+ const comparison = useCompare("Apfel", "Banane"); // -1
86
92
 
87
- #### Häufig verwendete Operatoren:
93
+ // Generiere Zufallszahl
94
+ const randomNum = useRandom(42); // Zufallszahl basierend auf Seed 42
95
+ ```
88
96
 
89
- | Methode | Beschreibung | Beispiel |
90
- |--------|-------------|---------|
91
- | `map(fn)` | Jedes Element transformieren | `.map(x => x * 2)` |
92
- | `filter(fn)` | Nur Elemente behalten, die den Prädikat erfüllen | `.filter(x => x > 10)` |
93
- | `limit(n)` | Maximale Anzahl von N Elementen | `.limit(5)` |
94
- | `skip(n)` | Erste N Elemente überspringen | `.skip(2)` |
95
- | `distinct()` | Duplikate entfernen (nutzt intern Set) | `.distinct()` |
96
- | `sorted()` | Elemente sortieren (natürliche Reihenfolge) | `.sorted()` |
97
- | `sorted(comparator)` | Mit benutzerdefinierter Sortierfunktion | `.sorted((a, b) => a - b)` |
98
- | `toOrdered()` | Sortieren und `OrderedCollectable` zurückgeben | `.toOrdered()` |
99
- | `toUnordered()` | **Keine Sortierung** – schnellster Weg | `.toUnordered()` ✅ |
100
- | `collect(collector)` | Mit einem Collector aggregieren | `.collect(Collector.full(...))` |
101
- | `toArray()` | In Array umwandeln | `.toArray()` |
102
- | `toSet()` | In Set umwandeln | `.toSet()` |
103
- | `toMap(keyFn, valFn)` | In Map umwandeln | `.toMap(x => x.id, x => x)` |
97
+ ## Kernklassen-Details
104
98
 
105
- ---
99
+ ### Optional<T> - Sichere Nullwert-Behandlung
106
100
 
107
- ### 3. `toUnordered()` 🚀 Am schnellsten, keine Sortierung
101
+ Die Optional-Klasse bietet einen funktionalen Ansatz zur sicheren Handhabung von Werten, die null oder undefined sein könnten.
108
102
 
109
- Wenn Sie **keine bestimmte Reihenfolge** benötigen und den **schnellsten möglichen Durchsatz** wünschen, verwenden Sie:
103
+ | Methode | Rückgabetyp | Beschreibung | Zeitkomplexität |
104
+ |------|----------|------|------------|
105
+ | `filter(predicate: Predicate<T>)` | `Optional<T>` | Filtere Werte, die Bedingung erfüllen | O(1) |
106
+ | `get()` | `T` | Hole Wert, wirft Fehler wenn leer | O(1) |
107
+ | `getOrDefault(defaultValue: T)` | `T` | Hole Wert oder Standardwert | O(1) |
108
+ | `ifPresent(action: Consumer<T>)` | `void` | Führe Aktion aus wenn Wert existiert | O(1) |
109
+ | `isEmpty()` | `boolean` | Prüfe ob leer | O(1) |
110
+ | `isPresent()` | `boolean` | Prüfe ob Wert existiert | O(1) |
111
+ | `map<R>(mapper: Functional<T, R>)` | `Optional<R>` | Mappe und transformiere Wert | O(1) |
112
+ | `static of<T>(value: MaybeInvalid<T>)` | `Optional<T>` | Erstelle Optional-Instanz | O(1) |
113
+ | `static ofNullable<T>(value?)` | `Optional<T>` | Erstelle nullable Optional | O(1) |
114
+ | `static ofNonNull<T>(value: T)` | `Optional<T>` | Erstelle Non-Null Optional | O(1) |
110
115
 
116
+ **Code-Beispiel-Ergänzung:**
111
117
  ```typescript
112
- const fastest = semanticStream.toUnordered();
113
- ```
118
+ import { Optional } from 'semantic-typescript';
114
119
 
115
- 🔥 **Es wird kein Sortieralgorithmus verwendet.**
116
- Idealerweise bei irrelevanter Reihenfolge und maximalem Performancebedarf.
120
+ // Erstelle Optional-Instanz
121
+ const optionalValue = Optional.ofNullable<string>(Math.random() > 0.5 ? "hallo" : null);
117
122
 
118
- ---
123
+ // Kettenoperationen
124
+ const result = optionalValue
125
+ .filter(val => val.length > 3) // Filtere Werte länger als 3
126
+ .map(val => val.toUpperCase()) // Konvertiere zu Großbuchstaben
127
+ .getOrDefault("standard"); // Hole Wert oder Standard
119
128
 
120
- ### 4. `toOrdered()` und `sorted()` Sortierte Ausgabe
129
+ console.log(result); // "HALLO" oder "standard"
121
130
 
122
- Wenn Sie eine **sortierte Ausgabe** benötigen, verwenden Sie:
131
+ // Sichere Operationen
132
+ optionalValue.ifPresent(val => {
133
+ console.log(`Wert existiert: ${val}`);
134
+ });
123
135
 
124
- ```typescript
125
- const ordered = semanticStream.sorted(); // Natürliche Sortierung
126
- const customSorted = semanticStream.sorted((a, b) => a - b); // Eigene Sortierlogik
127
- const orderedCollectable = semanticStream.toOrdered(); // Auch sortiert
136
+ // Prüfe Status
137
+ if (optionalValue.isPresent()) {
138
+ console.log("Hat Wert");
139
+ } else if (optionalValue.isEmpty()) {
140
+ console.log("Ist leer");
141
+ }
128
142
  ```
129
143
 
130
- ⚠️ Diese Methoden **sortieren die Elemente**, entweder nach natürlicher Ordnung oder mit einem angegebenen Comparator.
131
-
132
- ---
133
-
134
- ### 5. `Collector<E, A, R>` – Datensammlung / Aggregation
144
+ ### Semantic<E> - Lazy Datenstrom
145
+
146
+ Semantic ist die Kern-Stream-Verarbeitungsklasse und bietet reichhaltige Stream-Operatoren.
147
+
148
+ #### Stream-Transformations-Operationen
149
+
150
+ | Methode | Rückgabetyp | Beschreibung | Leistungsauswirkung |
151
+ |------|----------|------|----------|
152
+ | `concat(other: Semantic<E>)` | `Semantic<E>` | Verkette zwei Streams | O(n+m) |
153
+ | `distinct()` | `Semantic<E>` | Entferne Duplikate (mit Set) | O(n) |
154
+ | `distinct(comparator)` | `Semantic<E>` | Benutzerdefinierte Comparator-Deduplizierung | O(n²) |
155
+ | `dropWhile(predicate)` | `Semantic<E>` | Verwerfe Startelemente, die Bedingung erfüllen | O(n) |
156
+ | `filter(predicate)` | `Semantic<E>` | Filtere Elemente | O(n) |
157
+ | `flat(mapper)` | `Semantic<E>` | Glätte verschachtelte Streams | O(n×m) |
158
+ | `flatMap(mapper)` | `Semantic<R>` | Mappe und glätte | O(n×m) |
159
+ | `limit(n)` | `Semantic<E>` | Begrenze Anzahl der Elemente | O(n) |
160
+ | `map(mapper)` | `Semantic<R>` | Mappe und transformiere Elemente | O(n) |
161
+ | `peek(consumer)` | `Semantic<E>` | Betrachte Elemente ohne Modifikation | O(n) |
162
+ | `redirect(redirector)` | `Semantic<E>` | Leite Indizes um | O(n) |
163
+ | `reverse()` | `Semantic<E>` | Kehre Stream-Reihenfolge um | O(n) |
164
+ | `shuffle()` | `Semantic<E>` | Mische Reihenfolge zufällig | O(n) |
165
+ | `shuffle(mapper)` | `Semantic<E>` | Benutzerdefinierte Shuffle-Logik | O(n) |
166
+ | `skip(n)` | `Semantic<E>` | Überspringe erste n Elemente | O(n) |
167
+ | `sub(start, end)` | `Semantic<E>` | Hole Substream | O(n) |
168
+ | `takeWhile(predicate)` | `Semantic<E>` | Hole Startelemente, die Bedingung erfüllen | O(n) |
169
+ | `translate(offset)` | `Semantic<E>` | Übersetze Indizes | O(n) |
170
+ | `translate(translator)` | `Semantic<E>` | Benutzerdefinierte Index-Transformation | O(n) |
171
+
172
+ **Code-Beispiel-Ergänzung:**
173
+ ```typescript
174
+ import { from } from 'semantic-typescript';
135
175
 
136
- Mit Collectors können Sie Streams in **einzelne oder komplexe Strukturen** umwandeln.
176
+ const stream = from([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
137
177
 
138
- Eingebaute statische Factorys:
178
+ // Stream-Transformations-Operationsbeispiele
179
+ const processedStream = stream
180
+ .filter(x => x % 2 === 0) // Filtere gerade Zahlen
181
+ .map(x => x * 2) // Multipliziere jedes Element mit 2
182
+ .distinct() // Entferne Duplikate
183
+ .limit(3) // Begrenze auf erste 3 Elemente
184
+ .peek((val, index) => console.log(`Element ${val} an Index ${index}`)); // Betrachte Elemente
139
185
 
140
- ```typescript
141
- Collector.full(identity, accumulator, finisher)
142
- Collector.shortable(identity, interruptor, accumulator, finisher)
186
+ // Hinweis: Der Stream wurde noch nicht ausgeführt, muss zu Collectable konvertiert werden für Terminaloperationen
143
187
  ```
144
188
 
145
- In der Praxis werden Sie diese meist über die höherwertigen Methoden der `Collectable`-Klassen verwenden.
146
-
147
- ---
189
+ #### Stream-Terminaloperationen
148
190
 
149
- ### 6. `Collectable<E>` (abstrakte Klasse)
191
+ | Methode | Rückgabetyp | Beschreibung | Leistungscharakteristiken |
192
+ |------|----------|------|----------|
193
+ | `toOrdered()` | `OrderedCollectable<E>` | Konvertiere zu geordneter Sammlung | Sortieroperation, geringere Leistung |
194
+ | `toUnordered()` | `UnorderedCollectable<E>` | Konvertiere zu ungeordneter Sammlung | Schnellste, keine Sortierung |
195
+ | `toWindow()` | `WindowCollectable<E>` | Konvertiere zu Fenster-Sammlung | Sortieroperation, geringere Leistung |
196
+ | `toNumericStatistics()` | `Statistics<E, number>` | Numerische statistische Analyse | Sortieroperation, geringere Leistung |
197
+ | `toBigintStatistics()` | `Statistics<E, bigint>` | Big Integer statistische Analyse | Sortieroperation, geringere Leistung |
198
+ | `sorted()` | `OrderedCollectable<E>` | Natürliche Sortierung | Überschreibt Umleitungsergebnisse |
199
+ | `sorted(comparator)` | `OrderedCollectable<E>` | Benutzerdefinierte Sortierung | Überschreibt Umleitungsergebnisse |
150
200
 
151
- Basisklasse für:
152
-
153
- - `OrderedCollectable<E>` Sortierte Ausgabe
154
- - `UnorderedCollectable<E>` – Keine Sortierung, schnellster Weg
155
- - `WindowCollectable<E>` – Gleitende Fenster
156
- - `Statistics<E, D>` – Statistische Aggregation
201
+ **Code-Beispiel-Ergänzung:**
202
+ ```typescript
203
+ import { from } from 'semantic-typescript';
157
204
 
158
- #### Häufige Methoden (über Vererbung):
205
+ const semanticStream = from([5, 2, 8, 1, 9, 3, 7, 4, 6]);
159
206
 
160
- | Methode | Beschreibung | Beispiel |
161
- |--------|-------------|---------|
162
- | `count()` | Anzahl der Elemente | `.count()` |
163
- | `toArray()` | In Array umwandeln | `.toArray()` |
164
- | `toSet()` | In Set umwandeln | `.toSet()` |
165
- | `toMap(k, v)` | In Map umwandeln | `.toMap(x => x.id, x => x)` |
166
- | `group(k)` | Nach Schlüssel gruppieren | `.group(x => x.category)` |
167
- | `findAny()` | Beliebiges passendes Element (Optional) | `.findAny()` |
168
- | `findFirst()` | Erstes Element (Optional) | `.findFirst()` |
169
- | `reduce(...)` | Benutzerdefiniertes Reduzieren | `.reduce((a,b) => a + b, 0)` |
207
+ // Konvertiere zu geordneter Sammlung (geringere Leistung)
208
+ const ordered = semanticStream.toOrdered();
170
209
 
171
- ---
210
+ // Konvertiere zu ungeordneter Sammlung (schnellste)
211
+ const unordered = semanticStream.toUnordered();
172
212
 
173
- ### 7. `OrderedCollectable<E>` – Sortierte Daten
213
+ // Natürliche Sortierung
214
+ const sortedNatural = semanticStream.sorted();
174
215
 
175
- Wenn Sie möchten, dass die Elemente **automatisch sortiert** werden, verwenden Sie diese Klasse.
216
+ // Benutzerdefinierte Sortierung
217
+ const sortedCustom = semanticStream.sorted((a, b) => b - a); // Absteigende Sortierung
176
218
 
177
- Akzeptiert einen **benutzerdefinierten Comparator** oder nutzt die natürliche Sortierung.
219
+ // Konvertiere zu statistischem Objekt
220
+ const stats = semanticStream.toNumericStatistics();
178
221
 
179
- ```typescript
180
- const sorted = new OrderedCollectable(stream);
181
- const customSorted = new OrderedCollectable(stream, (a, b) => b - a);
222
+ // Hinweis: Muss obige Methoden durch Semantic-Instanz aufrufen, um Collectable zu erhalten, bevor Terminalmethoden verwendet werden
182
223
  ```
183
224
 
184
- 🔒 **Sortierte Ausgabe garantiert.**
185
-
186
- ---
225
+ ### Collector<E, A, R> - Datensammler
187
226
 
188
- ### 8. `UnorderedCollectable<E>` Keine Sortierung (🚀 Schnellster)
227
+ Collectors werden verwendet, um Stream-Daten in spezifische Strukturen zu aggregieren.
189
228
 
190
- Wenn Ihnen die **Reihenfolge egal** ist und Sie die **beste Performance** wünschen, verwenden Sie:
229
+ | Methode | Beschreibung | Verwendungsszenario |
230
+ |------|------|----------|
231
+ | `collect(generator)` | Führe Datensammlung aus | Stream-Terminaloperation |
232
+ | `static full(identity, accumulator, finisher)` | Erstelle vollständigen Collector | Erfordert vollständige Verarbeitung |
233
+ | `static shortable(identity, interruptor, accumulator, finisher)` | Erstelle unterbrechbaren Collector | Kann vorzeitig beendet werden |
191
234
 
235
+ **Code-Beispiel-Ergänzung:**
192
236
  ```typescript
193
- const unordered = new UnorderedCollectable(stream);
194
- // Oder
195
- const fastest = semanticStream.toUnordered();
237
+ import { Collector } from 'semantic-typescript';
238
+
239
+ // Erstelle benutzerdefinierten Collector
240
+ const sumCollector = Collector.full(
241
+ () => 0, // Initialwert
242
+ (acc, value) => acc + value, // Akkumulator
243
+ result => result // Finisher-Funktion
244
+ );
245
+
246
+ // Verwende Collector (erfordert Konvertierung von Semantic zu Collectable zuerst)
247
+ const numbers = from([1, 2, 3, 4, 5]);
248
+ const sum = numbers.toUnordered().collect(sumCollector); // 15
196
249
  ```
197
250
 
198
- **Kein Sortieralgorithmus wird ausgeführt**
199
- ✅ **Beste Performance, wenn Reihenfolge keine Rolle spielt**
200
-
201
- ---
251
+ ### Collectable<E> - Sammelbare Daten Abstrakte Klasse
202
252
 
203
- ### 9. `Statistics<E, D>` Statistische Analyse
253
+ Bietet reichhaltige Datenaggregations- und Transformationsmethoden. **Hinweis: Muss zuerst Collectable-Instanz erhalten, indem sorted(), toOrdered() etc. durch Semantic-Instanz aufgerufen werden, bevor die folgenden Methoden verwendet werden können.**
204
254
 
205
- Abstrakte Basisklasse zur Analyse numerischer Daten.
255
+ #### Datenabfrage-Operationen
206
256
 
207
- #### Unterklassen:
257
+ | Methode | Rückgabetyp | Beschreibung | Beispiel |
258
+ |------|----------|------|------|
259
+ | `anyMatch(predicate)` | `boolean` | Ob irgendein Element übereinstimmt | `anyMatch(x => x > 0)` |
260
+ | `allMatch(predicate)` | `boolean` | Ob alle Elemente übereinstimmen | `allMatch(x => x > 0)` |
261
+ | `count()` | `bigint` | Elementanzahl-Statistiken | `count()` → `5n` |
262
+ | `isEmpty()` | `boolean` | Ob Stream leer ist | `isEmpty()` |
263
+ | `findAny()` | `Optional<E>` | Finde irgendein Element | `findAny()` |
264
+ | `findFirst()` | `Optional<E>` | Finde erstes Element | `findFirst()` |
265
+ | `findLast()` | `Optional<E>` | Finde letztes Element | `findLast()` |
208
266
 
209
- - `NumericStatistics<E>` – Für `number`-Werte
210
- - `BigIntStatistics<E>` – Für `bigint`-Werte
211
-
212
- ##### Häufig verwendete statistische Methoden:
267
+ **Code-Beispiel-Ergänzung:**
268
+ ```typescript
269
+ import { from } from 'semantic-typescript';
213
270
 
214
- | Methode | Beschreibung | Beispiel |
215
- |--------|-------------|---------|
216
- | `mean()` | Mittelwert | `.mean()` |
217
- | `median()` | Median | `.median()` |
218
- | `mode()` | Modalwert (häufigster Wert) | `.mode()` |
219
- | `minimum()` | Minimum | `.minimum()` |
220
- | `maximum()` | Maximum | `.maximum()` |
221
- | `range()` | Maximum − Minimum | `.range()` |
222
- | `variance()` | Varianz | `.variance()` |
223
- | `standardDeviation()` | Standardabweichung | `.standardDeviation()` |
224
- | `summate()` | Summe aller Werte | `.summate()` |
225
- | `quantile(q)` | Quantil bei q (0–1) | `.quantile(0.5)` → Median |
226
- | `frequency()` | Häufigkeit als Map | `.frequency()` |
271
+ const numbers = from([1, 2, 3, 4, 5]);
227
272
 
228
- ---
273
+ // Muss zu Collectable konvertiert werden, bevor Terminalmethoden verwendet werden
274
+ const collectable = numbers.toUnordered();
229
275
 
230
- ## 🧪 Vollständiges Beispiel
276
+ // Datenabfrage-Operationen
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(); // Irgendein Element
283
+ ```
231
284
 
285
+ #### Datenaggregations-Operationen
286
+
287
+ | Methode | Rückgabetyp | Beschreibung | Komplexität |
288
+ |------|----------|------|--------|
289
+ | `group(classifier)` | `Map<K, E[]>` | Gruppiere nach Classifier | O(n) |
290
+ | `groupBy(keyExtractor, valueExtractor)` | `Map<K, V[]>` | Gruppiere nach Schlüssel-Wert-Extraktoren | O(n) |
291
+ | `join()` | `string` | Verbinde als String | O(n) |
292
+ | `join(delimiter)` | `string` | Verbinde mit Trennzeichen | O(n) |
293
+ | `partition(count)` | `E[][]` | Partitioniere nach Anzahl | O(n) |
294
+ | `partitionBy(classifier)` | `E[][]` | Partitioniere nach Classifier | O(n) |
295
+ | `reduce(accumulator)` | `Optional<E>` | Reduktionsoperation | O(n) |
296
+ | `reduce(identity, accumulator)` | `E` | Reduktion mit Identität | O(n) |
297
+ | `toArray()` | `E[]` | Konvertiere zu Array | O(n) |
298
+ | `toMap(keyExtractor, valueExtractor)` | `Map<K, V>` | Konvertiere zu Map | O(n) |
299
+ | `toSet()` | `Set<E>` | Konvertiere zu Set | O(n) |
300
+
301
+ **Code-Beispiel-Ergänzung:**
232
302
  ```typescript
233
- import { from, toUnordered, toOrdered, sorted, NumericStatistics } from 'semantic-typescript';
234
-
235
- // Beispiel-Daten
236
- const numbers = from([10, 2, 8, 4, 5, 6]);
237
-
238
- // 🚀 Schnellster Weg: keine Sortierung
239
- const fastest = numbers.toUnordered();
240
- console.log(fastest.toArray()); // z.B. [10, 2, 8, 4, 5, 6] (wie eingegeben)
241
-
242
- // 🔢 Natürlich sortiert
243
- const ordered = numbers.sorted();
244
- console.log(ordered.toArray()); // [2, 4, 5, 6, 8, 10]
245
-
246
- // 📊 Statistik auswerten
247
- const stats = new NumericStatistics(numbers);
248
- console.log('Mittelwert:', stats.mean());
249
- console.log('Median:', stats.median());
250
- console.log('Modalwert:', stats.mode());
251
- console.log('Bereich:', stats.range());
252
- console.log('Standardabweichung:', stats.standardDeviation());
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
+ // Muss zu Collectable konvertiert werden, bevor Aggregationsoperationen verwendet werden
312
+ const collectable = people.toUnordered();
313
+
314
+ // Gruppierungsoperationen
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
+ // Konvertiere zu Sammlungen
325
+ const array = collectable.toArray(); // Ursprüngliches Array
326
+ const set = collectable.toSet(); // Set-Sammlung
327
+ const map = collectable.toMap(
328
+ person => person.name,
329
+ person => person.age
330
+ ); // Map { "Alice" => 25, "Bob" => 30, "Charlie" => 25 }
331
+
332
+ // Reduktionsoperationen
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
+ ### Spezifische Collector-Implementierungen
256
338
 
257
- ## 🛠️ Hilfsfunktionen
339
+ #### UnorderedCollectable<E>
340
+ - **Charakteristiken**: Schnellster Collector, keine Sortierung
341
+ - **Verwendungsszenarien**: Reihenfolge unwichtig, maximale Leistung gewünscht
342
+ - **Methoden**: Erbt alle Collectable-Methoden
258
343
 
259
- Die Bibliothek exportiert auch zahlreiche **Typ-Guards** und **Vergleichsfunktionen**:
344
+ #### OrderedCollectable<E>
345
+ - **Charakteristiken**: Garantiert Elementreihenfolge, geringere Leistung
346
+ - **Verwendungsszenarien**: Erfordern sortierte Ergebnisse
347
+ - **Spezielle Methoden**: Erbt alle Methoden, behält internen Sortierzustand bei
260
348
 
261
- | Funktion | Zweck |
262
- |----------|-------|
263
- | `isString(x)` | Typ-Guard für `string` |
264
- | `isNumber(x)` | Typ-Guard für `number` |
265
- | `isBoolean(x)` | Typ-Guard für `boolean` |
266
- | `isIterable(x)` | Prüft, ob ein Objekt iterierbar ist |
267
- | `useCompare(a, b)` | Universelle Vergleichsfunktion |
268
- | `useRandom(x)` | Pseudo-Zufallszahlengenerator (spielerisch) |
349
+ #### WindowCollectable<E>
350
+ - **Charakteristiken**: Unterstützt Gleitfenster-Operationen
351
+ - **Verwendungsszenarien**: Zeitreihendatenanalyse
352
+ - **Spezielle Methoden**:
353
+ - `slide(size, step)` - Gleitfenster
354
+ - `tumble(size)` - Tumbling-Fenster
269
355
 
270
- ---
356
+ **Code-Beispiel-Ergänzung:**
357
+ ```typescript
358
+ import { from } from 'semantic-typescript';
271
359
 
272
- ## 🧩 Erweitert: Eigene Generatoren & Fenster
360
+ const data = from([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
273
361
 
274
- Sie können eigene **Generatoren** für kontrollierte oder unendliche Datenströme erstellen:
362
+ // Ungeordneter Collector (schnellste)
363
+ const unordered = data.toUnordered();
364
+ const unorderedArray = unordered.toArray(); // Kann ursprüngliche Reihenfolge beibehalten [1, 2, 3, ...]
275
365
 
276
- ```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);
285
- ```
366
+ // Geordneter Collector
367
+ const ordered = data.toOrdered();
368
+ const orderedArray = ordered.toArray(); // Garantiert sortiert [1, 2, 3, ...]
286
369
 
287
- Oder **gleitende Fenster** verwenden:
370
+ // Fenster-Collector
371
+ const windowed = data.toWindow();
372
+ const slidingWindows = windowed.slide(3n, 2n); // Fenstergröße 3, Schritt 2
373
+ // Fenster 1: [1, 2, 3], Fenster 2: [3, 4, 5], Fenster 3: [5, 6, 7], ...
288
374
 
289
- ```typescript
290
- const windowed = ordered.slide(3n, 2n); // Fenstergröße 3, Schritt 2
375
+ const tumblingWindows = windowed.tumble(4n); // Tumbling-Fenster Größe 4
376
+ // Fenster 1: [1, 2, 3, 4], Fenster 2: [5, 6, 7, 8], ...
291
377
  ```
292
378
 
293
- ---
294
-
295
- ## 📄 Lizenz
296
-
297
- Dieses Projekt steht unter der **MIT-Lizenz** – kostenlos für kommerzielle und private Nutzung.
379
+ ### Statistics<E, D> - Statistische Analyse
380
+
381
+ Statistische Analyse-Basisklasse, die reichhaltige statistische Berechnungsmethoden bietet. **Hinweis: Muss zuerst Statistics-Instanz erhalten, indem toNumericStatistics() oder toBigIntStatistics() durch Semantic-Instanz aufgerufen werden, bevor die folgenden Methoden verwendet werden können.**
382
+
383
+ #### Statistische Berechnungs-Operationen
384
+
385
+ | Methode | Rückgabetyp | Beschreibung | Algorithmus-Komplexität |
386
+ |------|----------|------|------------|
387
+ | `maximum()` | `Optional<E>` | Maximalwert | O(n) |
388
+ | `minimum()` | `Optional<E>` | Minimalwert | O(n) |
389
+ | `range()` | `D` | Bereich (max-min) | O(n) |
390
+ | `variance()` | `D` | Varianz | O(n) |
391
+ | `standardDeviation()` | `D` | Standardabweichung | O(n) |
392
+ | `mean()` | `D` | Mittelwert | O(n) |
393
+ | `median()` | `D` | Medianwert | O(n log n) |
394
+ | `mode()` | `D` | Modalwert | O(n) |
395
+ | `frequency()` | `Map<D, bigint>` | Häufigkeitsverteilung | O(n) |
396
+ | `summate()` | `D` | Summierung | O(n) |
397
+ | `quantile(quantile)` | `D` | Quantil | O(n log n) |
398
+ | `interquartileRange()` | `D` | Interquartilsabstand | O(n log n) |
399
+ | `skewness()` | `D` | Schiefe | O(n) |
400
+ | `kurtosis()` | `D` | Kurtosis | O(n) |
401
+
402
+ **Code-Beispiel-Ergänzung:**
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
+ // Muss zu statistischem Objekt konvertiert werden, bevor statistische Methoden verwendet werden
409
+ const stats = numbers.toNumericStatistics();
410
+
411
+ // Grundlegende Statistiken
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
+ // Erweiterte Statistiken
421
+ const variance = stats.variance(); // 8.25
422
+ const stdDev = stats.standardDeviation(); // 2.872
423
+ const mode = stats.mode(); // Irgendein Wert (da alle einmal erscheinen)
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
+ // Häufigkeitsverteilung
429
+ const freq = stats.frequency(); // Map {1 => 1n, 2 => 1n, ...}
430
+ ```
298
431
 
299
- ---
432
+ #### Spezifische Statistische Implementierungsklassen
300
433
 
301
- ## 🙌 Mitwirken
434
+ **NumericStatistics<E>**
435
+ - Verarbeitet number-Typ statistische Analyse
436
+ - Alle statistischen Berechnungen geben number-Typ zurück
302
437
 
303
- Pull Requests, Issues und Ideen sind willkommen!
438
+ **BigIntStatistics<E>**
439
+ - Verarbeitet bigint-Typ statistische Analyse
440
+ - Alle statistischen Berechnungen geben bigint-Typ zurück
304
441
 
305
- ---
442
+ **Code-Beispiel-Ergänzung:**
443
+ ```typescript
444
+ import { from } from 'semantic-typescript';
306
445
 
307
- ## 🚀 Schnellstart-Zusammenfassung
446
+ // Numerische Statistiken
447
+ const numberData = from([10, 20, 30, 40, 50]);
448
+ const numericStats = numberData.toNumericStatistics();
308
449
 
309
- | Aufgabe | Methode |
310
- |--------|---------|
311
- | Null-sicheres Arbeiten | `Optional<T>` |
312
- | Stream erstellen | `from([...])`, `range()`, `fill()` |
313
- | Daten transformieren | `map()`, `filter()` |
314
- | Daten sortieren | `sorted()`, `toOrdered()` |
315
- | Keine Sortierung (schnell) | `toUnordered()` ✅ |
316
- | Gruppieren / Aggregieren | `toMap()`, `group()`, `Collector` |
317
- | Statistik | `NumericStatistics`, `mean()`, `median()` usw. |
450
+ console.log(numericStats.mean()); // 30
451
+ console.log(numericStats.summate()); // 150
318
452
 
319
- ---
453
+ // Big Integer Statistiken
454
+ const bigintData = from([100n, 200n, 300n, 400n, 500n]);
455
+ const bigintStats = bigintData.toBigIntStatistics();
320
456
 
321
- ## 🔗 Links
457
+ console.log(bigintStats.mean()); // 300n
458
+ console.log(bigintStats.summate()); // 1500n
322
459
 
323
- - 📦 npm: https://www.npmjs.com/package/semantic-typescript
324
- - 🐙 GitHub: https://github.com/eloyhere/semantic-typescript
325
- - 📘 Dokumentation: Siehe Quellcode / Typdefinitionen
460
+ // Statistiken mit Mapper-Funktionen
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
- **Genießen Sie komponierbares, typsicheres und funktionales Datenhandling in TypeScript.** 🚀
473
+ ## Vollständiges Verwendungsbeispiel
330
474
 
331
- ---
475
+ ```typescript
476
+ import { from, validate, invalidate } from 'semantic-typescript';
477
+
478
+ // 1. Erstelle Datenstrom
479
+ const rawData = [5, 2, 8, 1, null, 9, 3, undefined, 7, 4, 6];
480
+ const semanticStream = from(rawData);
481
+
482
+ // 2. Stream-Verarbeitungspipeline
483
+ const processedStream = semanticStream
484
+ .filter(val => validate(val)) // Filtere null und undefined heraus
485
+ .map(val => val! * 2) // Multipliziere jeden Wert mit 2 (verwende !, da validate sicherstellt, dass nicht leer)
486
+ .distinct(); // Entferne Duplikate
487
+
488
+ // 3. Konvertiere zu Collectable und verwende Terminaloperationen
489
+ const collectable = processedStream.toUnordered();
490
+
491
+ // 4. Datenvalidierung und Verwendung
492
+ if (!collectable.isEmpty()) {
493
+ const results = collectable
494
+ .filter(x => x > 5) // Filtere erneut
495
+ .toArray(); // Konvertiere zu Array
496
+
497
+ console.log("Verarbeitungsergebnisse:", results); // [16, 18, 14, 8, 12]
498
+
499
+ // Statistische Informationen
500
+ const stats = processedStream.toNumericStatistics();
501
+ console.log("Mittelwert:", stats.mean()); // 11.2
502
+ console.log("Gesamtsumme:", stats.summate()); // 56
503
+ }
504
+
505
+ // 5. Behandle potenziell ungültige Daten
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("Gültige Daten:", validData); // [1, 3, 4]
511
+ console.log("Ungültige Daten:", invalidData); // [null, null]
512
+ ```
332
513
 
333
- **Wichtig:**
334
- - `toUnordered()` → **Keine Sortierung, schnellster Weg**
335
- - Alle anderen (z. B. `sorted()`, `toOrdered()`) **Sortieren die Daten**
514
+ ## Wichtige Verwendungsregeln Zusammenfassung
515
+
516
+ 1. **Erstelle Stream**: Verwende `from()`, `range()`, `fill()` etc. Factory-Methoden, um Semantic-Instanzen zu erstellen
517
+ 2. **Stream-Transformation**: Rufe `map()`, `filter()`, `distinct()` etc. Methoden auf Semantic-Instanzen auf
518
+ 3. **Konvertiere zu Collectable**: Muss eine der folgenden Methoden durch Semantic-Instanz aufrufen:
519
+ - `toOrdered()` - Geordneter Collector
520
+ - `toUnordered()` - Ungeordneter Collector (schnellste)
521
+ - `toWindow()` - Fenster-Collector
522
+ - `toNumericStatistics()` - Numerische Statistiken
523
+ - `toBigIntStatistics()` - Big Integer Statistiken
524
+ - `sorted()` - Natürliche Sortierung
525
+ - `sorted(comparator)` - Benutzerdefinierte Sortierung
526
+ 4. **Terminaloperationen**: Rufe `toArray()`, `count()`, `summate()` etc. Terminalmethoden auf Collectable-Instanzen auf
527
+ 5. **Datenvalidierung**: Verwende `validate()` um sicherzustellen, dass Daten nicht null/undefined sind, verwende `invalidate()` um ungültige Daten zu prüfen
528
+
529
+ Dieses Design gewährleistet Typsicherheit und Leistungsoptimierung, während es gleichzeitig reichhaltige Stream-Verarbeitungsfunktionalität bietet.