semantic-typescript 0.5.3 → 0.6.0
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/asynchronous/collector.d.ts +231 -0
- package/dist/asynchronous/collector.js +800 -0
- package/dist/asynchronous/semantic.d.ts +257 -0
- package/dist/asynchronous/semantic.js +1853 -0
- package/dist/factory.d.ts +71 -37
- package/dist/factory.js +443 -262
- package/dist/guard.d.ts +24 -14
- package/dist/guard.js +73 -19
- package/dist/hook.d.ts +6 -6
- package/dist/hook.js +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +2 -2
- package/dist/optional.d.ts +2 -2
- package/dist/symbol.d.ts +19 -10
- package/dist/symbol.js +19 -10
- package/dist/synchronous/collector.d.ts +232 -0
- package/dist/{collector.js → synchronous/collector.js} +160 -151
- package/dist/{semantic.d.ts → synchronous/semantic.d.ts} +111 -120
- package/dist/{semantic.js → synchronous/semantic.js} +299 -337
- package/dist/utility.d.ts +7 -1
- package/dist/utility.js +1 -0
- package/package.json +1 -1
- package/readme.cn.md +158 -697
- package/readme.de.md +163 -432
- package/readme.es.md +163 -433
- package/readme.fr.md +162 -444
- package/readme.jp.md +162 -442
- package/readme.kr.md +161 -430
- package/readme.md +157 -1009
- package/readme.ru.md +161 -426
- package/readme.tw.md +161 -436
- package/dist/collector.d.ts +0 -236
- package/dist/main.d.ts +0 -1
- package/dist/main.js +0 -4
- package/dist/map.d.ts +0 -76
- package/dist/map.js +0 -245
- package/dist/node.d.ts +0 -182
- package/dist/node.js +0 -918
- package/dist/set.d.ts +0 -19
- package/dist/set.js +0 -65
- package/dist/tree.d.ts +0 -82
- package/dist/tree.js +0 -257
package/readme.de.md
CHANGED
|
@@ -1,483 +1,214 @@
|
|
|
1
|
-
# Semantic-TypeScript Stream
|
|
1
|
+
# Semantic-TypeScript: Eine bahnbrechende Stream-Processing-Bibliothek
|
|
2
2
|
|
|
3
|
-
##
|
|
3
|
+
## Einführung
|
|
4
|
+
Semantic-TypeScript stellt einen bedeutenden Fortschritt in der Stream-Processing-Technologie dar und vereint die effektivsten Konzepte aus JavaScript GeneratorFunctions, Java Streams und Datenbank-Indizierungs-Paradigmen. Ihr grundlegendes Designprinzip zielt darauf ab, durch ausgeklügelte verzögerte Auswertung (Lazy Evaluation) und intelligente Indizierung äußerst effiziente Datenverarbeitungspipelines zu konstruieren. Die Bibliothek bietet eine streng typensichere, funktional reine Streaming-Operation-Erfahrung, die speziell für die moderne TypeScript- und JavaScript-Entwicklung entwickelt wurde.
|
|
4
5
|
|
|
5
|
-
Semantic-TypeScript
|
|
6
|
+
Im Gegensatz zu herkömmlichen synchronen Verarbeitungsarchitekturen implementiert Semantic-TypeScript ein einheitliches Modell, das sowohl synchrone (Iterable) als auch asynchrone (AsyncIterable) Datenquellen elegant behandelt. Während der Stream-Erzeugung werden der Fluss und die Beendigung von Daten präzise durch Callback-Mechanismen gesteuert, was es der Bibliothek ermöglicht, mit außergewöhnlicher Anmut zu arbeiten:
|
|
6
7
|
|
|
7
|
-
|
|
8
|
+
- Echtzeit-Datenströme (DOM-Events, WebSockets, Intervalle) mit deterministischer Kontrolle
|
|
9
|
+
- Große Datensätze über speichereffiziente, verzögerte Pipelines
|
|
10
|
+
- Komplexe Datentransformationen mit einer fließenden, deklarativen API
|
|
8
11
|
|
|
9
|
-
|
|
12
|
+
Der innovative Ansatz der Bibliothek überdenkt grundlegend, wie Entwickler mit Datenfolgen interagieren, und bietet beispiellose Leistungsmerkmale und Entwicklerfreundlichkeit in einem einzigen, kohärenten Paket.
|
|
10
13
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
```
|
|
14
|
+
## Kernphilosophie: Trennung von Definition und Ausführung
|
|
15
|
+
Eine zentrale architektonische Erkenntnis von Semantic-TypeScript ist die klare Trennung zwischen der Definition eines Streams und seiner Ausführung:
|
|
14
16
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
| Typ | Beschreibung |
|
|
18
|
-
|------|-------------|
|
|
19
|
-
| `Invalid<T>` | Typ, der sich von `null` oder `undefined` ableitet |
|
|
20
|
-
| `Valid<T>` | Typ, der `null` und `undefined` ausschließt |
|
|
21
|
-
| `MaybeInvalid<T>` | Typ, der `null` oder `undefined` sein kann |
|
|
22
|
-
| `Primitive` | Sammlung primitiver Typen |
|
|
23
|
-
| `MaybePrimitive<T>` | Typ, der ein primitiver Typ sein kann |
|
|
24
|
-
| `OptionalSymbol` | Symbolbezeichner der `Optional`-Klasse |
|
|
25
|
-
| `SemanticSymbol` | Symbolbezeichner der `Semantic`-Klasse |
|
|
26
|
-
| `CollectorsSymbol` | Symbolbezeichner der `Collector`-Klasse |
|
|
27
|
-
| `CollectableSymbol` | Symbolbezeichner der `Collectable`-Klasse |
|
|
28
|
-
| `OrderedCollectableSymbol` | Symbolbezeichner der `OrderedCollectable`-Klasse |
|
|
29
|
-
| `WindowCollectableSymbol` | Symbolbezeichner der `WindowCollectable`-Klasse |
|
|
30
|
-
| `StatisticsSymbol` | Symbolbezeichner der `Statistics`-Klasse |
|
|
31
|
-
| `NumericStatisticsSymbol` | Symbolbezeichner der `NumericStatistics`-Klasse |
|
|
32
|
-
| `BigIntStatisticsSymbol` | Symbolbezeichner der `BigIntStatistics`-Klasse |
|
|
33
|
-
| `UnorderedCollectableSymbol` | Symbolbezeichner der `UnorderedCollectable`-Klasse |
|
|
34
|
-
|
|
35
|
-
## Funktionsorientierte Schnittstellen
|
|
36
|
-
|
|
37
|
-
| Schnittstelle | Beschreibung |
|
|
38
|
-
|-----------|-------------|
|
|
39
|
-
| `Runnable` | Funktion ohne Parameter und ohne Rückgabewert |
|
|
40
|
-
| `Supplier<R>` | Funktion ohne Parameter, die `R` zurückgibt |
|
|
41
|
-
| `Functional<T, R>` | Einzelparameter-Transformationsfunktion |
|
|
42
|
-
| `BiFunctional<T, U, R>` | Zweiparameter-Transformationsfunktion |
|
|
43
|
-
| `TriFunctional<T, U, V, R>` | Dreiparameter-Transformationsfunktion |
|
|
44
|
-
| `Predicate<T>` | Einzelparameter-Prädikatfunktion |
|
|
45
|
-
| `BiPredicate<T, U>` | Zweiparameter-Prädikatfunktion |
|
|
46
|
-
| `TriPredicate<T, U, V>` | Dreiparameter-Prädikatfunktion |
|
|
47
|
-
| `Consumer<T>` | Einzelparameter-Consumerfunktion |
|
|
48
|
-
| `BiConsumer<T, U>` | Zweiparameter-Consumerfunktion |
|
|
49
|
-
| `TriConsumer<T, U, V>` | Dreiparameter-Consumerfunktion |
|
|
50
|
-
| `Comparator<T>` | Zweiparameter-Vergleichsfunktion |
|
|
51
|
-
| `Generator<T>` | Generatorfunktion (Kern und Basis) |
|
|
17
|
+
- **Semantic<E>**: Eine unveränderliche, verzögerte Blaupause einer Datentransformationspipeline. Sie definiert, welche Operationen (Filter, Map usw.) ausgeführt werden.
|
|
18
|
+
- **Collectable<E>**: Eine materialisierte, ausführbare Ansicht des Streams. Sie wird von einem Semantic erhalten und stellt alle Terminaloperationen (collect, forEach usw.) zur Ausführung der Pipeline und Erzeugung eines Ergebnisses bereit.
|
|
52
19
|
|
|
53
|
-
|
|
54
|
-
// Beispiel für die Verwendung von Typen
|
|
55
|
-
let predicate: Predicate<number> = (n: number): boolean => n > 0;
|
|
56
|
-
let mapper: Functional<string, number> = (text: string): number => text.length;
|
|
57
|
-
let comparator: Comparator<number> = (a: number, b: number): number => a - b;
|
|
58
|
-
```
|
|
20
|
+
Diese Trennung erzwingt ein klares mentales Modell und ermöglicht leistungsstarke Optimierungen, wie z. B. die Auswahl eines UnorderedCollectable, um unnötige Sortiervorgänge für maximale Geschwindigkeit zu überspringen.
|
|
59
21
|
|
|
60
|
-
##
|
|
61
|
-
|
|
62
|
-
| Funktion | Beschreibung | Zeitkomplexität | Speicherplatzkomplexität |
|
|
63
|
-
|------|------|------------|------------|
|
|
64
|
-
| `validate<T>(t: MaybeInvalid<T>): t is T` | Überprüft, ob der Wert nicht null oder undefined ist | O(1) | O(1) |
|
|
65
|
-
| `invalidate<T>(t: MaybeInvalid<T>): t is null \| undefined` | Überprüft, ob der Wert null oder undefined ist | O(1) | O(1) |
|
|
66
|
-
| `isBoolean(t: unknown): t is boolean` | Überprüft, ob es sich um einen booleschen Wert handelt | O(1) | O(1) |
|
|
67
|
-
| `isString(t: unknown): t is string` | Überprüft, ob es sich um einen String handelt | O(1) | O(1) |
|
|
68
|
-
| `isNumber(t: unknown): t is number` | Überprüft, ob es sich um eine Zahl handelt | O(1) | O(1) |
|
|
69
|
-
| `isFunction(t: unknown): t is Function` | Überprüft, ob es sich um eine Funktion handelt | O(1) | O(1) |
|
|
70
|
-
| `isObject(t: unknown): t is object` | Überprüft, ob es sich um ein Objekt handelt | O(1) | O(1) |
|
|
71
|
-
| `isSymbol(t: unknown): t is symbol` | Überprüft, ob es sich um ein Symbol handelt | O(1) | O(1) |
|
|
72
|
-
| `isBigint(t: unknown): t is bigint` | Überprüft, ob es sich um ein BigInt handelt | O(1) | O(1) |
|
|
73
|
-
| `isPrimitive(t: unknown): t is Primitive` | Überprüft, ob es sich um einen primitiven Typ handelt | O(1) | O(1) |
|
|
74
|
-
| `isIterable(t: unknown): t is Iterable<unknown>` | Überprüft, ob es sich um ein iterierbares Objekt handelt | O(1) | O(1) |
|
|
75
|
-
| `isOptional(t: unknown): t is Optional<unknown>` | Überprüft, ob es sich um eine Optional-Instanz handelt | O(1) | O(1) |
|
|
76
|
-
| `isSemantic(t: unknown): t is Semantic<unknown>` | Überprüft, ob es sich um eine Semantic-Instanz handelt | O(1) | O(1) |
|
|
77
|
-
| `isCollector(t: unknown): t is Collector<unknown, unknown, unknown>` | Überprüft, ob es sich um eine Collector-Instanz handelt | O(1) | O(1) |
|
|
78
|
-
| `isCollectable(t: unknown): t is Collectable<unknown>` | Überprüft, ob es sich um eine Collectable-Instanz handelt | O(1) | O(1) |
|
|
79
|
-
| `isOrderedCollectable(t: unknown): t is OrderedCollectable<unknown>` | Überprüft, ob es sich um eine OrderedCollectable-Instanz handelt | O(1) | O(1) |
|
|
80
|
-
| `isWindowCollectable(t: unknown): t is WindowCollectable<unknown>` | Überprüft, ob es sich um eine WindowCollectable-Instanz handelt | O(1) | O(1) |
|
|
81
|
-
| `isUnorderedCollectable(t: unknown): t is UnorderedCollectable<unknown>` | Überprüft, ob es sich um eine UnorderedCollectable-Instanz handelt | O(1) | O(1) |
|
|
82
|
-
| `isStatistics(t: unknown): t is Statistics<unknown, number \| bigint>` | Überprüft, ob es sich um eine Statistics-Instanz handelt | O(1) | O(1) |
|
|
83
|
-
| `isNumericStatistics(t: unknown): t is NumericStatistics<unknown>` | Überprüft, ob es sich um eine NumericStatistics-Instanz handelt | O(1) | O(1) |
|
|
84
|
-
| `isBigIntStatistics(t: unknown): t is BigIntStatistics<unknown>` | Überprüft, ob es sich um eine BigIntStatistics-Instanz handelt | O(1) | O(1) |
|
|
85
|
-
| `isPromise(t: unknown): t is Promise<unknown>` | Überprüft, ob es sich um ein Promise-Objekt handelt | O(1) | O(1) |
|
|
86
|
-
| `isAsync(t: unknown): t is AsyncFunction` | Überprüft, ob es sich um eine AsyncFunction handelt | O(1) | O(1) |
|
|
22
|
+
## Warum Semantic-TypeScript wählen?
|
|
23
|
+
Die Wahl der richtigen Bibliothek für die Verarbeitung von Datenströmen erfordert eine Abwägung zwischen Leistung, Typsicherheit und Ausdruckskraft. Semantic-TypeScript ist so konzipiert, dass es in all diesen Dimensionen herausragt.
|
|
87
24
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
let value: unknown = "hello";
|
|
25
|
+
### 1. Ein einheitliches, typsicheres Paradigma für alle Datenfolgen
|
|
26
|
+
Es bietet eine konsistente, deklarative API zur Verarbeitung jeder Datenfolge – sei es statische Arrays, Echtzeit-Ereignisse oder asynchrone Datenblöcke – und nutzt gleichzeitig die volle Leistungsfähigkeit von TypeScript, um eine Ende-zu-Ende-Typsicherheit zu gewährleisten. Dadurch wird eine ganze Klasse von Laufzeitfehlern eliminiert und die Stream-Manipulation in eine vorhersehbare, vom Compiler überprüfte Aktivität verwandelt.
|
|
91
27
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
}
|
|
28
|
+
### 2. Kompromisslose Leistung durch intelligente Verzögerung (Lazy Evaluation)
|
|
29
|
+
Im Kern basiert die Bibliothek auf Lazy Evaluation. Operationen wie Filter, Map und FlatMap komponieren lediglich eine Verarbeitungspipeline; es wird keine Arbeit ausgeführt, bis eine Terminaloperation aufgerufen wird. Dies wird mit Short-Circuiting-Fähigkeiten (über limit, anyMatch oder benutzerdefinierte Unterbrechungs-Callbacks) kombiniert, wodurch die Verarbeitung vorzeitig gestoppt werden kann, was die Effizienz für große oder unendliche Ströme erheblich verbessert.
|
|
95
30
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
}
|
|
31
|
+
### 3. Die Leistungsfähigkeit des `Collector<E, A, R>`-Musters
|
|
32
|
+
Inspiriert von Java ist das Collector-Muster der Motor der Flexibilität. Es entkoppelt die Spezifikation, wie Stream-Elemente akkumuliert werden sollen, von der Ausführung des Streams selbst. Die Bibliothek bietet eine reichhaltige Auswahl an integrierten Collectors (toArray, groupBy, summate usw.) für alltägliche Aufgaben und macht es gleichzeitig einfach, eigene komplexe, wiederverwendbare Reduktionslogiken zu implementieren. Dies ist weitaus leistungsfähiger und komponierbarer als ein fester Satz von Terminalmethoden.
|
|
99
33
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
for(let item of value){
|
|
103
|
-
console.log(item);
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
```
|
|
34
|
+
### 4. Erstklassige Unterstützung für moderne Web- und asynchrone Daten
|
|
35
|
+
Semantic-TypeScript ist für die moderne Entwicklung konzipiert. Es bietet native Factory-Methoden für moderne Web-Quellen:
|
|
107
36
|
|
|
108
|
-
|
|
37
|
+
- `useFrom(iterable)`, `useRange()` für statische Daten
|
|
38
|
+
- `useInterval()`, `useAnimationFrame()` für zeitbasierte Ströme
|
|
39
|
+
- `useBlob()` für die blockweise Verarbeitung von Binärdaten
|
|
40
|
+
- `useWebSocket()`, `useDocument()`, `useWindow()` für Echtzeit-Ereignisströme
|
|
109
41
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
| `useCompare<T>(t1: T, t2: T): number` | Allgemeine Vergleichsfunktion | O(1) | O(1) |
|
|
113
|
-
| `useRandom<T = number \| bigint>(index: T): T` | Pseudozufallszahlengenerator | O(log n) | O(1) |
|
|
42
|
+
### 5. Jenseits der grundlegenden Aggregation: Integrierte statistische Analyse
|
|
43
|
+
Gehen Sie über einfache Summen und Durchschnitte hinaus. Die Bibliothek bietet dedizierte NumericStatistics- und BigIntStatistics-Schnittstellen, die sofortigen Zugang zu fortschrittlichen statistischen Kennzahlen direkt aus Ihren Strömen ermöglichen – Varianz, Standardabweichung, Median, Schiefe und Kurtosis. Dies verwandelt komplexe Datenanalysen in eine einzelne Codezeile.
|
|
114
44
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
45
|
+
### 6. Für eine hervorragende Entwickler-Ergonomie gestaltet
|
|
46
|
+
- **Fließende, verkettbare API**: Schreiben Sie komplexe Datenpipelines als lesbare, sequentielle Ketten.
|
|
47
|
+
- **Umfassendes Utility-Set**: Wesentliche Guards (isFunction, isIterable), Utilities (useCompare, useTraverse) und funktionale Schnittstellen sind enthalten.
|
|
48
|
+
- **Optional<T>-Integration**: Modelliert sicher das Fehlen eines Werts und eliminiert Nullzeiger-Probleme.
|
|
49
|
+
- **Leistungsanleitung**: Klare Hinweise, wann ungeordnete Sammlungen für Geschwindigkeit gegenüber geordneten für die Reihenfolge zu verwenden sind.
|
|
119
50
|
|
|
120
|
-
|
|
51
|
+
## Installation
|
|
52
|
+
```bash
|
|
53
|
+
npm install semantic-typescript
|
|
121
54
|
```
|
|
122
55
|
|
|
123
|
-
##
|
|
56
|
+
## Kernkonzepte in der Praxis
|
|
124
57
|
|
|
125
|
-
###
|
|
126
|
-
|
|
127
|
-
| Methode | Beschreibung | Zeitkomplexität | Speicherplatzkomplexität |
|
|
128
|
-
|------|------|------------|------------|
|
|
129
|
-
| `Optional.empty<T>()` | Erstellt eine leere Optional | O(1) | O(1) |
|
|
130
|
-
| `Optional.of<T>(value)` | Erstellt eine Optional, die einen Wert enthält | O(1) | O(1) |
|
|
131
|
-
| `Optional.ofNullable<T>(value)` | Erstellt eine potenziell leere Optional | O(1) | O(1) |
|
|
132
|
-
| `Optional.ofNonNull<T>(value)` | Erstellt eine nicht-null Optional | O(1) | O(1) |
|
|
58
|
+
### 1. Streams erstellen (Semantic)
|
|
59
|
+
Streams können aus verschiedenen Quellen mithilfe von Factory-Funktionen erstellt werden.
|
|
133
60
|
|
|
134
61
|
```typescript
|
|
135
|
-
|
|
136
|
-
let empty: Optional<number> = Optional.empty();
|
|
137
|
-
let present: Optional<number> = Optional.of(42);
|
|
138
|
-
let nullable: Optional<string> = Optional.ofNullable<string>(null);
|
|
139
|
-
let nonNull: Optional<string> = Optional.ofNonNull("hello");
|
|
140
|
-
|
|
141
|
-
present.ifPresent((value: number): void => console.log(value)); // Gibt 42 aus
|
|
142
|
-
console.log(empty.get(100)); // Gibt 100 aus
|
|
143
|
-
```
|
|
62
|
+
import { useFrom, useInterval, useDocument } from 'semantic-typescript';
|
|
144
63
|
|
|
145
|
-
|
|
64
|
+
// Aus einem statischen Array
|
|
65
|
+
const staticStream = useFrom([1, 2, 3, 4, 5]);
|
|
146
66
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
67
|
+
// Aus einem asynchronen Generator
|
|
68
|
+
const asyncStream = useFrom(async function*() {
|
|
69
|
+
yield 1;
|
|
70
|
+
yield 2;
|
|
71
|
+
});
|
|
151
72
|
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
let numbers: Semantic<number> = from([3, 1, 4, 1, 5, 9, 2, 6, 5]);
|
|
155
|
-
|
|
156
|
-
// Leistung zuerst: verwenden Sie den ungeordneten Collector
|
|
157
|
-
let unordered: UnorderedCollectable<number> = from([3, 1, 4, 1, 5, 9, 2, 6, 5])
|
|
158
|
-
.filter((n: number): boolean => n > 3)
|
|
159
|
-
.toUnordered();
|
|
160
|
-
|
|
161
|
-
// Sortierung erforderlich: verwenden Sie den geordneten Collector
|
|
162
|
-
let ordered: OrderedCollectable<number> = from([3, 1, 4, 1, 5, 9, 2, 6, 5])
|
|
163
|
-
.sorted();
|
|
164
|
-
|
|
165
|
-
// Zählt die Anzahl der Elemente
|
|
166
|
-
let count: Collector<number, number, number> = Collector.full(
|
|
167
|
-
(): number => 0, // Anfangswert
|
|
168
|
-
(accumulator: number, element: number): number => accumulator + element, // Akkumulieren
|
|
169
|
-
(accumulator: number): number => accumulator // Fertigstellen
|
|
170
|
-
);
|
|
171
|
-
count.collect(from([1,2,3,4,5])); // Zählt aus einem Stream
|
|
172
|
-
count.collect([1,2,3,4,5]); // Zählt aus einem iterierbaren Objekt
|
|
173
|
-
|
|
174
|
-
let find: Optional<number> = Collector.shortable(
|
|
175
|
-
(): Optional<number> => Optional.empty(), // Anfangswert
|
|
176
|
-
(element: number, index: bigint, accumulator: Optional<number>): Optional<number> => accumulator.isPresent(), // Unterbrechen
|
|
177
|
-
(accumulator: Optional<number>, element: number, index: bigint): Optional<number> => Optional.of(element), // Akkumulieren
|
|
178
|
-
(accumulator: Optional<number>): Optional<number> => accumulator // Fertigstellen
|
|
179
|
-
);
|
|
180
|
-
find.collect(from([1,2,3,4,5])); // Findet das erste Element
|
|
181
|
-
find.collect([1,2,3,4,5]); // Findet das erste Element
|
|
182
|
-
```
|
|
183
|
-
|
|
184
|
-
### Semantic Fabrikmethoden
|
|
73
|
+
// Ein zeitbasierter Stream
|
|
74
|
+
const tickStream = useInterval(1000); // emittiert jede Sekunde
|
|
185
75
|
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
| `animationFrame(period: number, delay: number = 0)` | Erstellt einen zeitgesteuerten Animationsframe-Stream | O(1)* | O(1) |
|
|
189
|
-
| `blob(blob, chunkSize)` | Erstellt einen Stream aus einem Blob | O(n) | O(chunkSize) |
|
|
190
|
-
| `empty<E>()` | Erstellt einen leeren Stream | O(1) | O(1) |
|
|
191
|
-
| `fill<E>(element, count)` | Erstellt einen gefüllten Stream | O(n) | O(1) |
|
|
192
|
-
| `from<E>(iterable)` | Erstellt einen Stream aus einem iterierbaren Objekt | O(1) | O(1) |
|
|
193
|
-
| `interval(period, delay?)` | Erstellt einen zeitgesteuerten Intervall-Stream | O(1)* | O(1) |
|
|
194
|
-
| `iterate<E>(generator)` | Erstellt einen Stream aus einem Generator | O(1) | O(1) |
|
|
195
|
-
| `range(start, end, step)` | Erstellt einen numerischen Bereichs-Stream | O(n) | O(1) |
|
|
196
|
-
| `websocket(websocket)` | Erstellt einen Stream aus einem WebSocket | O(1) | O(1) |
|
|
197
|
-
|
|
198
|
-
```typescript
|
|
199
|
-
// Beispiele für die Verwendung von Semantic Fabrikmethoden
|
|
200
|
-
|
|
201
|
-
// Erstellt einen Stream aus einem zeitgesteuerten Animationsframe
|
|
202
|
-
animationFrame(1000)
|
|
203
|
-
.toUnordered()
|
|
204
|
-
.forEach(frame => console.log(frame));
|
|
205
|
-
|
|
206
|
-
// Erstellt einen Stream aus einem Blob (chunked reading)
|
|
207
|
-
blob(someBlob, 1024n)
|
|
208
|
-
.toUnordered()
|
|
209
|
-
.write(WritableStream)
|
|
210
|
-
.then(callback) // Schreiben des Streams erfolgreich
|
|
211
|
-
.catch(callback); // Schreiben des Streams fehlgeschlagen
|
|
212
|
-
|
|
213
|
-
// Erstellt einen leeren Stream, der erst ausgeführt wird, wenn er mit anderen Streams verkettet wird
|
|
214
|
-
empty<string>()
|
|
215
|
-
.toUnordered()
|
|
216
|
-
.join(); //[]
|
|
217
|
-
|
|
218
|
-
// Erstellt einen gefüllten Stream
|
|
219
|
-
let filledStream = fill("hello", 3); // "hello", "hello", "hello"
|
|
220
|
-
|
|
221
|
-
// Erstellt einen zeitgesteuerten Stream mit einer anfänglichen Verzögerung von 2 Sekunden und einer Ausführungsperiode von 5 Sekunden, implementiert auf der Grundlage eines Timer-Mechanismus; kann aufgrund von Systemplanungsgenauigkeitsbeschränkungen zu Zeitdrift führen.
|
|
222
|
-
let intervalStream = interval(5000, 2000);
|
|
223
|
-
|
|
224
|
-
// Erstellt einen Stream aus einem iterierbaren Objekt
|
|
225
|
-
let numberStream = from([1, 2, 3, 4, 5]);
|
|
226
|
-
let stringStream = from(new Set(["Alex", "Bob"]));
|
|
227
|
-
|
|
228
|
-
// Erstellt einen Bereichs-Stream
|
|
229
|
-
let rangeStream = range(1, 10, 2); // 1, 3, 5, 7, 9
|
|
230
|
-
|
|
231
|
-
// WebSocket-Ereignis-Stream
|
|
232
|
-
let ws = new WebSocket("ws://localhost:8080");
|
|
233
|
-
websocket(ws)
|
|
234
|
-
.filter((event): boolean => event.type === "message"); // Nur Nachrichtenereignisse abhören
|
|
235
|
-
.toUnordered() // Ereignisse sind in der Regel nicht geordnet
|
|
236
|
-
.forEach((event): void => receive(event)); // Nachrichten empfangen
|
|
76
|
+
// Ein DOM-Ereignisstream (siehe wichtigen Hinweis unten)
|
|
77
|
+
const clickStream = useDocument('click');
|
|
237
78
|
```
|
|
238
79
|
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
| Methode | Beschreibung | Zeitkomplexität | Speicherplatzkomplexität |
|
|
242
|
-
|------|------|------------|------------|
|
|
243
|
-
| `concat(other)` | Verbindet zwei Streams | O(n) | O(1) |
|
|
244
|
-
| `distinct()` | Entfernt Duplikate | O(n) | O(n) |
|
|
245
|
-
| `distinct(comparator)` | Entfernt Duplikate mit einem Vergleichsoperator | O(n²) | O(n) |
|
|
246
|
-
| `dropWhile(predicate)` | Verwirft Elemente, die die Bedingung erfüllen | O(n) | O(1) |
|
|
247
|
-
| `filter(predicate)` | Filtert Elemente | O(n) | O(1) |
|
|
248
|
-
| `flat(mapper)` | Flachemapping | O(n × m) | O(1) |
|
|
249
|
-
| `flatMap(mapper)` | Flachemapping in einen neuen Typ | O(n × m) | O(1) |
|
|
250
|
-
| `limit(n)` | Begrenzt die Anzahl der Elemente | O(n) | O(1) |
|
|
251
|
-
| `map(mapper)` | Zuordnungstransformation | O(n) | O(1) |
|
|
252
|
-
| `peek(consumer)` | Blickt auf Elemente | O(n) | O(1) |
|
|
253
|
-
| `redirect(redirector)` | Leitet den Index um | O(n) | O(1) |
|
|
254
|
-
| `reverse()` | Umkehrt den Stream | O(n) | O(1) |
|
|
255
|
-
| `shuffle()` | Mischt zufällig | O(n) | O(1) |
|
|
256
|
-
| `shuffle(mapper)` | Mischt mit einem Mapper | O(n) | O(1) |
|
|
257
|
-
| `skip(n)` | Überspringt die ersten n Elemente | O(n) | O(1) |
|
|
258
|
-
| `sorted()` | Sortiert | O(n log n) | O(n) |
|
|
259
|
-
| `sorted(comparator)` | Sortiert mit einem Vergleichsoperator | O(n log n) | O(n) |
|
|
260
|
-
| `sub(start, end)` | Holt einen Substream | O(n) | O(1) |
|
|
261
|
-
| `takeWhile(predicate)` | Holt Elemente, die die Bedingung erfüllen | O(n) | O(1) |
|
|
262
|
-
| `translate(offset)` | Übersetzt den Index | O(n) | O(1) |
|
|
263
|
-
| `translate(translator)` | Übersetzt den Index mit einem Translator | O(n) | O(1) |
|
|
80
|
+
### 2. Streams transformieren (Zwischenoperationen)
|
|
81
|
+
Operationen werden träge verkettet, um die Pipeline zu definieren.
|
|
264
82
|
|
|
265
83
|
```typescript
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
.limit(3) // Begrenzt auf 3 Elemente
|
|
272
|
-
.toUnordered() // Konvertiert in einen ungeordneten Collector
|
|
273
|
-
.toArray(); // Konvertiert in ein Array
|
|
274
|
-
// Ergebnis: [8, 12, 20]
|
|
275
|
-
|
|
276
|
-
// Komplexes Operationsexample
|
|
277
|
-
let complexResult = range(1, 100, 1)
|
|
278
|
-
.flatMap((n: number): Semantics<number> => from([n, n * 2])) // Mappt jedes Element auf zwei
|
|
279
|
-
.distinct() // Entfernt Duplikate
|
|
280
|
-
.shuffle() // Mischt die Reihenfolge
|
|
281
|
-
.takeWhile((n: number): boolean => n < 50) // Nimmt Elemente kleiner als 50
|
|
282
|
-
.toOrdered() // Konvertiert in einen geordneten Collector
|
|
283
|
-
.toArray(); // Konvertiert in ein Array
|
|
284
|
-
```
|
|
285
|
-
|
|
286
|
-
## Semantic Konvertierungsmethoden
|
|
84
|
+
const processedStream = staticStream
|
|
85
|
+
.filter(x => x % 2 === 0) // Nur gerade Zahlen behalten
|
|
86
|
+
.map(x => x * 10) // Mit 10 multiplizieren
|
|
87
|
+
.flatMap(x => [x, x + 1]) // Jedes Element in zwei umwandeln
|
|
88
|
+
.distinct(); // Duplikate entfernen
|
|
287
89
|
|
|
288
|
-
|
|
289
|
-
|------------|------------|------------|------------|
|
|
290
|
-
| `sorted()` | Konvertiert in einen geordneten Collector | O(n log n) | O(n) |
|
|
291
|
-
| `toUnordered()` | Konvertiert in einen ungeordneten Collector | O(1) | O(1) |
|
|
292
|
-
| `toOrdered()` | Konvertiert in einen geordneten Collector | O(1) | O(1) |
|
|
293
|
-
| `toNumericStatistics()` | Konvertiert in numerische Statistiken | O(n) | O(1) |
|
|
294
|
-
| `toBigintStatistics()` | Konvertiert in BigInt-Statistiken | O(n) | O(1) |
|
|
295
|
-
| `toWindow()` | Konvertiert in einen Fenstercollector | O(1) | O(1) |
|
|
296
|
-
| `toCollectable()` | Konvertiert in `UnorderdCollectable` | O(n) | O(1) |
|
|
297
|
-
| `toCollectable(mapper)` | Konvertiert in einen benutzerdefinierten Collectable | O(n) | O(1) |
|
|
298
|
-
|
|
299
|
-
```typescript
|
|
300
|
-
// Konvertiert in ein aufsteigend sortiertes Array
|
|
301
|
-
from([6,4,3,5,2]) // Erstellt einen Stream
|
|
302
|
-
.sorted() // Sortiert den Stream in aufsteigender Reihenfolge
|
|
303
|
-
.toArray(); // [2, 3, 4, 5, 6]
|
|
304
|
-
|
|
305
|
-
// Konvertiert in ein absteigend sortiertes Array
|
|
306
|
-
from([6,4,3,5,2]) // Erstellt einen Stream
|
|
307
|
-
.soted((a: number, b: number): number => b - a) // Sortiert den Stream in absteigender Reihenfolge
|
|
308
|
-
.toArray(); // [6, 5, 4, 3, 2]
|
|
309
|
-
|
|
310
|
-
// Leitet um in ein umgekehrtes Array
|
|
311
|
-
from([6,4,3,5,2])
|
|
312
|
-
.redirect((element, index): bigint => -index) // Leitet um in umgekehrter Reihenfolge
|
|
313
|
-
.toOrderd() // Behält die umgeleitete Reihenfolge bei
|
|
314
|
-
.toArray(); // [2, 5, 3, 4, 6]
|
|
315
|
-
|
|
316
|
-
// Ignoriert Umleitungen, um ein umgekehrtes Array zu erhalten
|
|
317
|
-
from([6,4,3,5,2])
|
|
318
|
-
.redirect((element: number, index: bigint) => -index) // Leitet um in umgekehrter Reihenfolge
|
|
319
|
-
.toUnorderd() // Ignoriert die umgeleitete Reihenfolge. Diese Operation ignoriert `redirect`, `reverse`, `shuffle` und `translate` Operationen
|
|
320
|
-
.toArray(); // [2, 5, 3, 4, 6]
|
|
321
|
-
|
|
322
|
-
// Kehrt den Stream in ein Array um
|
|
323
|
-
from([6, 4, 3, 5, 2])
|
|
324
|
-
.reverse() // Kehrt den Stream um
|
|
325
|
-
.toOrdered() // Garantiert die umgekehrte Reihenfolge
|
|
326
|
-
.toArray(); // [2, 5, 3, 4, 6]
|
|
327
|
-
|
|
328
|
-
// Überschreibt den gemischten Stream in ein Array
|
|
329
|
-
from([6, 4, 3, 5, 2])
|
|
330
|
-
.shuffle() // Mischt den Stream
|
|
331
|
-
.sorted() // Überschreibt die gemischte Reihenfolge. Diese Operation überschreibt `redirect`, `reverse`, `shuffle` und `translate` Operationen
|
|
332
|
-
.toArray(); // [2, 5, 3, 4, 6]
|
|
333
|
-
|
|
334
|
-
// Konvertiert in einen Fenstercollector
|
|
335
|
-
from([6, 4, 3, 5, 2]).toWindow();
|
|
336
|
-
|
|
337
|
-
// Konvertiert in numerische Statistiken
|
|
338
|
-
from([6, 4, 3, 5, 2]).toNumericStatistics();
|
|
339
|
-
|
|
340
|
-
// Konvertiert in BigInt-Statistiken
|
|
341
|
-
from([6n, 4n, 3n, 5n, 2n]).toBigintStatistics();
|
|
342
|
-
|
|
343
|
-
// Definiert einen benutzerdefinierten Collector zum Sammeln von Daten
|
|
344
|
-
let customizedCollector = from([1, 2, 3, 4, 5]).toCollectable((generator: Generator<E>) => new CustomizedCollector(generator));
|
|
90
|
+
// Bisher wurde noch nichts ausgeführt
|
|
345
91
|
```
|
|
346
92
|
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
| Methode | Beschreibung | Zeitkomplexität | Speicherplatzkomplexität |
|
|
350
|
-
|------|------|------------|------------|
|
|
351
|
-
| `anyMatch(predicate)` | Ob irgendein Element übereinstimmt | O(n) | O(1) |
|
|
352
|
-
| `allMatch(predicate)` | Ob alle Elemente übereinstimmen | O(n) | O(1) |
|
|
353
|
-
| `count()` | Elementanzahl | O(n) | O(1) |
|
|
354
|
-
| `isEmpty()` | Ob es leer ist | O(1) | O(1) |
|
|
355
|
-
| `findAny()` | Finde ein beliebiges Element | O(n) | O(1) |
|
|
356
|
-
| `findFirst()` | Finde das erste Element | O(n) | O(1) |
|
|
357
|
-
| `findLast()` | Finde das letzte Element | O(n) | O(1) |
|
|
358
|
-
| `forEach(action)` | Durchlaufe alle Elemente | O(n) | O(1) |
|
|
359
|
-
| `group(classifier)` | Gruppiere nach Klassifizierer | O(n) | O(n) |
|
|
360
|
-
| `groupBy(keyExtractor, valueExtractor)` | Gruppiere nach Schlüssel-Wert-Extraktor | O(n) | O(n) |
|
|
361
|
-
| `join()` | Verbinde als Zeichenkette | O(n) | O(n) |
|
|
362
|
-
| `join(delimiter)` | Verbinde mit einem Trennzeichen | O(n) | O(n) |
|
|
363
|
-
| `nonMatch(predicate)` | Ob kein Element übereinstimmt | O(n) | O(1) |
|
|
364
|
-
| `partition(count)` | Partitioniere nach Anzahl | O(n) | O(n) |
|
|
365
|
-
| `partitionBy(classifier)` | Partitioniere nach Klassifizierer | O(n) | O(n) |
|
|
366
|
-
| `reduce(accumulator)` | Reduktionsoperation | O(n) | O(1) |
|
|
367
|
-
| `reduce(identity, accumulator)` | Reduzierung mit Anfangswert | O(n) | O(1) |
|
|
368
|
-
| `toArray()` | Konvertiere in ein Array | O(n) | O(n) |
|
|
369
|
-
| `toMap(keyExtractor, valueExtractor)` | Konvertiere in eine Map | O(n) | O(n) |
|
|
370
|
-
| `toSet()` | Konvertiere in eine Menge | O(n) | O(n) |
|
|
371
|
-
| `write(stream)` | Schreibe in einen Stream | O(n) | O(1) |
|
|
93
|
+
### 3. Streams ausführen (Terminaloperationen)
|
|
94
|
+
Um ein Ergebnis zu erhalten, müssen Sie ein Collectable erhalten und eine Terminaloperation aufrufen.
|
|
372
95
|
|
|
373
96
|
```typescript
|
|
374
|
-
// Collectable
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
console.log(
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
let grouped = data.groupBy(
|
|
389
|
-
(n: number): string => (n > 5 ? "groß" : "klein"),
|
|
390
|
-
(n: number): number => n * 2
|
|
391
|
-
); // {klein: [4, 8], groß: [12, 16, 20]}
|
|
392
|
-
|
|
393
|
-
// Reduktionsvorgänge
|
|
394
|
-
let sum = data.reduce(0, (acc, n) => acc + n); // 30
|
|
395
|
-
|
|
396
|
-
// Ausgabeoperationen
|
|
397
|
-
data.join(", "); // "[2, 4, 6, 8, 10]"
|
|
97
|
+
// Ein ungeordnetes Collectable für Leistung erhalten
|
|
98
|
+
const resultArray = await processedStream.toUnordered().toArray();
|
|
99
|
+
console.log(resultArray); // z.B. [20, 21, 40, 41]
|
|
100
|
+
|
|
101
|
+
// Einen eingebauten Collector verwenden
|
|
102
|
+
const sum = await processedStream.toUnordered().collect(useSummate());
|
|
103
|
+
console.log(sum);
|
|
104
|
+
|
|
105
|
+
// Oder die generische collect-Methode verwenden
|
|
106
|
+
const customResult = await processedStream.toOrdered().collect(
|
|
107
|
+
() => new Map<number, number>(),
|
|
108
|
+
(map, element, index) => map.set(index, element),
|
|
109
|
+
map => map
|
|
110
|
+
);
|
|
398
111
|
```
|
|
399
112
|
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
### NumericStatistics Methoden
|
|
403
|
-
|
|
404
|
-
| Methode | Beschreibung | Zeitkomplexität | Speicherplatzkomplexität |
|
|
405
|
-
|------|------|------------|------------|
|
|
406
|
-
| `range()` | Bereich | O(n) | O(1) |
|
|
407
|
-
| `variance()` | Varianz | O(n) | O(1) |
|
|
408
|
-
| `standardDeviation()` | Standardabweichung | O(n) | O(1) |
|
|
409
|
-
| `mean()` | Mittelwert | O(n) | O(1) |
|
|
410
|
-
| `median()` | Median | O(n log n) | O(n) |
|
|
411
|
-
| `mode()` | Modus | O(n) | O(n) |
|
|
412
|
-
| `frequency()` | Häufigkeitsverteilung | O(n) | O(n) |
|
|
413
|
-
| `summate()` | Summation | O(n) | O(1) |
|
|
414
|
-
| `quantile(quantile)` | Quantil | O(n log n) | O(n) |
|
|
415
|
-
| `interquartileRange()` | Interquartilsabstand | O(n log n) | O(n) |
|
|
416
|
-
| `skewness()` | Schiefe | O(n) | O(1) |
|
|
417
|
-
| `kurtosis()` | Wölbung | O(n) | O(1) |
|
|
113
|
+
### 4. Wichtig: Umgang mit Ereignisströmen
|
|
114
|
+
Ereignisströme (useDocument, useWindow, useHTMLElement, useWebSocket) sind von Natur aus unendlich. Sie müssen Operationen wie sub, takeWhile oder limit verwenden, um zu definieren, wann das Sammeln von Ereignissen beendet und der Stream abgeschlossen werden soll. Andernfalls wartet die Terminaloperation unendlich lange.
|
|
418
115
|
|
|
419
116
|
```typescript
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
117
|
+
import { useDocument } from 'semantic-typescript';
|
|
118
|
+
|
|
119
|
+
// Nur die ersten 5 Klicks sammeln
|
|
120
|
+
const first5Clicks = await useDocument('click')
|
|
121
|
+
.limit(5) // <- Essentiell: Begrenzt den Stream auf 5 Ereignisse
|
|
122
|
+
.toUnordered()
|
|
123
|
+
.toArray();
|
|
124
|
+
|
|
125
|
+
// Klicks in einem 10-Sekunden-Fenster sammeln
|
|
126
|
+
const clicksIn10s = await useDocument('click')
|
|
127
|
+
.takeWhile((_, index, startTime = Date.now()) => Date.now() - startTime < 10000)
|
|
128
|
+
.toUnordered()
|
|
129
|
+
.toArray();
|
|
130
|
+
|
|
131
|
+
// Klicks von Index 2 bis 5 sammeln (0-basiert)
|
|
132
|
+
const specificClicks = await useDocument('click')
|
|
133
|
+
.sub(2n, 6n) // <- Nimmt Elemente mit Index 2, 3, 4, 5
|
|
134
|
+
.toUnordered()
|
|
135
|
+
.toArray();
|
|
436
136
|
```
|
|
437
137
|
|
|
438
|
-
|
|
138
|
+
**Wichtige Erkenntnis**: Das Ereignis (z. B. ein MouseEvent) und sein sequenzieller Auslöseindex (als BigInt) werden über den Callback `accept(event, index)` gemeinsam durch die Pipeline geleitet.
|
|
439
139
|
|
|
440
|
-
###
|
|
140
|
+
### 5. Statistikfunktionen nutzen
|
|
441
141
|
```typescript
|
|
442
|
-
|
|
443
|
-
let highPerformance = data
|
|
444
|
-
.filter(predicate)
|
|
445
|
-
.map(mapper)
|
|
446
|
-
.toUnordered(); // Beste Leistung
|
|
447
|
-
```
|
|
142
|
+
const numericStream = useFrom([10, 20, 30, 40, 50]).toNumeric();
|
|
448
143
|
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
```
|
|
144
|
+
const average = await numericStream.average();
|
|
145
|
+
const median = await numericStream.median();
|
|
146
|
+
const standardDeviation = await numericStream.standardDeviation();
|
|
147
|
+
const skewness = await numericStream.skewness();
|
|
454
148
|
|
|
455
|
-
|
|
456
|
-
```typescript
|
|
457
|
-
// Wenn Fensteroperationen benötigt werden
|
|
458
|
-
let window: WindowCollectable<number> = data
|
|
459
|
-
.toWindow()
|
|
460
|
-
.slide(5n, 2n); // Gleitender Fenster
|
|
149
|
+
console.log(`Durchschnitt: ${average}, Median: ${median}, Standardabweichung: ${standardDeviation}`);
|
|
461
150
|
```
|
|
462
151
|
|
|
463
|
-
|
|
152
|
+
## Hauptmerkmale
|
|
153
|
+
- **Duale Stream-Typen**: Volle Unterstützung für sowohl SynchronousSemantic (für Iterable) als auch AsynchronousSemantic (für AsyncIterable und Ereignisse)
|
|
154
|
+
- **Umfangreicher Operationensatz**: filter, map, flatMap, concat, distinct, sorted, limit, skip, peek, reverse, shuffle
|
|
155
|
+
- **Flexible Terminaloperationen**: collect (mit benutzerdefinierten Collectors), toArray, toSet, toMap, forEach, reduce, findFirst, anyMatch, allMatch, count
|
|
156
|
+
- **Erweiterte Collector**: Eingebaute Collector für joining, groupingBy, partitioningBy, summing, averaging, maxBy, minBy
|
|
157
|
+
- **Statistikmodul**: Gebrauchsfertige Methoden für Mittelwert, Median, Modus, Varianz, Standardabweichung, Bereich, Quantile, Schiefe, Kurtosis für numerische/BigInt-Streams
|
|
158
|
+
- **Hilfsfunktionen**: Typ-Guards (isPromise, isAsyncIterable), Komparatoren (useCompare), Traversal (useTraverse) und Konvertierungs-Hooks
|
|
159
|
+
- **Optional<T>**: Ein monadischer Container für nullable Werte, integriert mit Suchoperationen
|
|
160
|
+
|
|
161
|
+
## API-Übersicht
|
|
162
|
+
### Kernklassen und -schnittstellen
|
|
163
|
+
- `Semantic<E>` / `AsynchronousSemantic<E>`: Die abstrakte Stream-Definition
|
|
164
|
+
- `Collectable<E>` / `AsynchronousCollectable<E>`: Der ausführbare Stream mit Terminaloperationen
|
|
165
|
+
- `OrderedCollectable<E>` / `UnorderedCollectable<E>`: Materialisierte Versionen, optimiert für reihenfolgensensitive oder reihenfolgenunempfindliche Operationen
|
|
166
|
+
- `Collector<E, A, R>`: Die Abstraktion für mutable Reduktionsoperationen
|
|
167
|
+
|
|
168
|
+
### Factory-Funktionen (use*)
|
|
169
|
+
- **Aus Quellen**: useFrom, useRange, useFill, useEmpty
|
|
170
|
+
- **Aus Zeit**: useInterval, useAnimationFrame
|
|
171
|
+
- **Aus Web-APIs**: useBlob, useDocument, useWindow, useHTMLElement, useWebSocket
|
|
172
|
+
- **Collector**: useToArray, useGroupBy, useSummate, useJoin, usw.
|
|
173
|
+
|
|
174
|
+
## Leistungshinweise
|
|
175
|
+
- **Lazy Evaluation**: Pipelines werden ohne Ausführung komponiert, bis eine Terminaloperation aufgerufen wird
|
|
176
|
+
- **Short-Circuiting**: Operationen wie limit, anyMatch und findFirst stoppen die Verarbeitung von Elementen, sobald das Ergebnis bestimmt ist
|
|
177
|
+
- **Geordnet vs. Ungeordnet**:
|
|
178
|
+
- Verwenden Sie `.toUnordered()` für Terminaloperationen, wenn die Reihenfolge der Quellelemente für Ihr Ergebnis keine Rolle spielt (z. B. für Summe, Maximum oder toSet). Dies kann interne Optimierungen ermöglichen, die kostspielige Sortierschritte überspringen
|
|
179
|
+
- Verwenden Sie `.toOrdered()`, wenn die Reihenfolge wichtig ist (z. B. für toArray, bei dem die Reihenfolge erhalten bleiben muss)
|
|
180
|
+
|
|
181
|
+
## Einstiegsbeispiel
|
|
464
182
|
```typescript
|
|
465
|
-
|
|
466
|
-
let statistics: NumericStatistics<number> = data
|
|
467
|
-
.toNumericStatistics(); // Numerische Statistiken
|
|
183
|
+
import { useFrom, useSummate, useGroupBy } from 'semantic-typescript';
|
|
468
184
|
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
[NPMJS](https://www.npmjs.com/package/semantic-typescript)
|
|
185
|
+
interface Transaction {
|
|
186
|
+
id: number;
|
|
187
|
+
amount: number;
|
|
188
|
+
category: string;
|
|
189
|
+
}
|
|
475
190
|
|
|
476
|
-
|
|
191
|
+
const transactions: Transaction[] = [
|
|
192
|
+
{ id: 1, amount: 100, category: 'Food' },
|
|
193
|
+
{ id: 2, amount: 200, category: 'Electronics' },
|
|
194
|
+
{ id: 3, amount: 50, category: 'Food' },
|
|
195
|
+
{ id: 4, amount: 300, category: 'Electronics' },
|
|
196
|
+
];
|
|
197
|
+
|
|
198
|
+
// Gesamtbetrag pro Kategorie berechnen
|
|
199
|
+
const totalsByCategory = await useFrom(transactions)
|
|
200
|
+
.toUnordered()
|
|
201
|
+
.collect(
|
|
202
|
+
useGroupBy(
|
|
203
|
+
t => t.category,
|
|
204
|
+
t => t.amount,
|
|
205
|
+
useSummate() // Collector für die Werte
|
|
206
|
+
)
|
|
207
|
+
);
|
|
208
|
+
|
|
209
|
+
console.log(totalsByCategory); // Map { 'Food' => 150, 'Electronics' => 500 }
|
|
210
|
+
```
|
|
477
211
|
|
|
478
|
-
|
|
479
|
-
2. **Leistungserwägungen**: Wenn keine Reihenfolgegarantie benötigt wird, bevorzugen Sie die Verwendung von `toUnordered()` für eine bessere Leistung.
|
|
480
|
-
3. **Speicherverwendung**: Sortiervorgänge erfordern zusätzlichen Speicherplatz von O(n).
|
|
481
|
-
4. **Echtzeitdaten**: Semantic-Streams eignen sich für die Verarbeitung von Echtzeitdaten und unterstützen asynchrone Datenquellen.
|
|
212
|
+
Semantic-TypeScript wurde für Entwickler gebaut, die eine streng entworfene, typsichere und leistungsstarke Stream-Processing-Bibliothek suchen. Es bringt die Leistungsfähigkeit von Unternehmens-Datentransformationsmustern in das TypeScript-Ökosystem und eignet sich perfekt für datenintensive Frontend-Anwendungen, Node.js-Datenverarbeitung und jedes Szenario, in dem elegante, effiziente Handhabung von Sequenzen erforderlich ist.
|
|
482
213
|
|
|
483
|
-
|
|
214
|
+
[](https://github.com/eloyhere/semantic-typescript) [](https://www.npmjs.com/package/semantic-typescript)
|