semantic-typescript 0.0.7 → 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/package.json +1 -1
- 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 +441 -247
- package/readme.md +434 -240
- package/readme.ru.md +529 -0
- package/readme.tw.md +441 -247
package/readme.md
CHANGED
|
@@ -1,335 +1,529 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Semantic-TypeScript Stream Processing Framework
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
Provides composable, functional-style constructs for working with collections, streams, and sequences — with support for sorting, filtering, grouping, statistics, and more.
|
|
3
|
+
## Introduction
|
|
5
4
|
|
|
6
|
-
|
|
5
|
+
Semantic-TypeScript is a modern stream processing library inspired by JavaScript GeneratorFunction, Java Stream, and MySQL Index. The core design philosophy is based on constructing efficient data processing pipelines through data indexing, providing a type-safe, functional-style streaming operation experience for frontend development.
|
|
7
6
|
|
|
8
|
-
|
|
7
|
+
Unlike traditional synchronous processing, Semantic employs an asynchronous processing model. When creating data streams, the timing of terminal data reception depends entirely on when upstream calls the `accept` and `interrupt` callback functions. This design enables the library to elegantly handle real-time data streams, large datasets, and asynchronous data sources.
|
|
9
8
|
|
|
10
|
-
##
|
|
9
|
+
## Core Features
|
|
11
10
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
- ✅ **Iterators & Generators** based design — suitable for large or asynchronous data
|
|
11
|
+
| Feature | Description | Advantage |
|
|
12
|
+
|------|------|------|
|
|
13
|
+
| **Type-Safe Generics** | Complete TypeScript type support | Compile-time error detection, better development experience |
|
|
14
|
+
| **Functional Programming** | Immutable data structures and pure functions | More predictable code, easier testing and maintenance |
|
|
15
|
+
| **Lazy Evaluation** | On-demand computation, performance optimisation | High memory efficiency when processing large datasets |
|
|
16
|
+
| **Asynchronous Stream Processing** | Generator-based asynchronous data streams | Suitable for real-time data and event-driven scenarios |
|
|
17
|
+
| **Multi-Paradigm Collectors** | Ordered, unordered, statistical collection strategies | Optimal strategy selection based on different scenarios |
|
|
18
|
+
| **Statistical Analysis** | Built-in complete statistical calculation functions | Integrated data analysis and reporting generation |
|
|
21
19
|
|
|
22
|
-
|
|
20
|
+
## Performance Considerations
|
|
23
21
|
|
|
24
|
-
|
|
22
|
+
**Important Note**: The following methods sacrifice performance to collect and sort data, resulting in ordered data collections:
|
|
23
|
+
- `toOrdered()`
|
|
24
|
+
- `toWindow()`
|
|
25
|
+
- `toNumericStatistics()`
|
|
26
|
+
- `toBigIntStatistics()`
|
|
27
|
+
- `sorted()`
|
|
28
|
+
- `sorted(comparator)`
|
|
25
29
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
---
|
|
31
|
-
|
|
32
|
-
## 🧠 Core Concepts
|
|
33
|
-
|
|
34
|
-
### 1. `Optional<T>` – Safe Nullable Handling
|
|
35
|
-
|
|
36
|
-
A monadic container for values that may be `null` or `undefined`.
|
|
30
|
+
Particularly important to note: `sorted()` and `sorted(comparator)` will override the results of the following methods:
|
|
31
|
+
- `redirect(redirector)`
|
|
32
|
+
- `translate(translator)`
|
|
33
|
+
- `shuffle(mapper)`
|
|
37
34
|
|
|
38
|
-
|
|
35
|
+
## Factory Methods
|
|
39
36
|
|
|
40
|
-
|
|
41
|
-
|----------------|--------------------------------------------------|---------|
|
|
42
|
-
| `of(value)` | Wrap a value (may be nullish) | `Optional.of(null)` |
|
|
43
|
-
| `ofNullable(v)`| Wrap, allowing nullish values | `Optional.ofNullable(someVar)` |
|
|
44
|
-
| `ofNonNull(v)` | Wrap, throws if null/undefined | `Optional.ofNonNull(5)` |
|
|
45
|
-
| `get()` | Retrieve value or throw if empty | `opt.get()` |
|
|
46
|
-
| `getOrDefault(d)`| Retrieve value or default | `opt.getOrDefault(0)` |
|
|
47
|
-
| `ifPresent(fn)`| Execute side-effect if present | `opt.ifPresent(x => console.log(x))` |
|
|
48
|
-
| `map(fn)` | Transform value if present | `opt.map(x => x + 1)` |
|
|
49
|
-
| `filter(fn)` | Retain value only if predicate passes | `opt.filter(x => x > 0)` |
|
|
50
|
-
| `isEmpty()` | Check if empty | `opt.isEmpty()` |
|
|
51
|
-
| `isPresent()` | Check if contains a value | `opt.isPresent()` |
|
|
37
|
+
### Stream Creation Factories
|
|
52
38
|
|
|
53
|
-
|
|
39
|
+
| Method | Signature | Description | Example |
|
|
40
|
+
|------|------|------|------|
|
|
41
|
+
| `blob` | `(blob: Blob, chunk?: bigint) => Semantic<Uint8Array>` | Convert Blob to byte stream | `blob(fileBlob, 1024n)` |
|
|
42
|
+
| `empty` | `<E>() => Semantic<E>` | Create empty stream | `empty<number>()` |
|
|
43
|
+
| `fill` | `<E>(element: E, count: bigint) => Semantic<E>` | Fill with specified number of elements | `fill("hello", 5n)` |
|
|
44
|
+
| `from` | `<E>(iterable: Iterable<E>) => Semantic<E>` | Create stream from iterable object | `from([1, 2, 3])` |
|
|
45
|
+
| `range` | `<N extends number\|bigint>(start: N, end: N, step?: N) => Semantic<N>` | Create numerical range stream | `range(1, 10, 2)` |
|
|
46
|
+
| `iterate` | `<E>(generator: Generator<E>) => Semantic<E>` | Create stream from generator function | `iterate(myGenerator)` |
|
|
47
|
+
| `websocket` | `(websocket: WebSocket) => Semantic<MessageEvent>` | Create event stream from WebSocket | `websocket(socket)` |
|
|
54
48
|
|
|
49
|
+
**Code Example Supplement:**
|
|
55
50
|
```typescript
|
|
56
|
-
import {
|
|
51
|
+
import { from, range, fill, empty } from 'semantic-typescript';
|
|
57
52
|
|
|
58
|
-
|
|
53
|
+
// Create stream from array
|
|
54
|
+
const numberStream = from([1, 2, 3, 4, 5]);
|
|
59
55
|
|
|
60
|
-
|
|
56
|
+
// Create numerical range stream
|
|
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
|
+
// Fill with repeated elements
|
|
60
|
+
const filledStream = fill("hello", 3n); // "hello", "hello", "hello"
|
|
66
61
|
|
|
67
|
-
|
|
62
|
+
// Create empty stream
|
|
63
|
+
const emptyStream = empty<number>();
|
|
68
64
|
```
|
|
69
65
|
|
|
70
|
-
|
|
66
|
+
### Utility Function Factories
|
|
71
67
|
|
|
72
|
-
|
|
68
|
+
| Method | Signature | Description | Example |
|
|
69
|
+
|------|------|------|------|
|
|
70
|
+
| `validate` | `<T>(t: MaybeInvalid<T>) => t is T` | Validate if value is valid | `validate(null)` → `false` |
|
|
71
|
+
| `invalidate` | `<T>(t: MaybeInvalid<T>) => t is null\|undefined` | Validate if value is invalid | `invalidate(0)` → `false` |
|
|
72
|
+
| `useCompare` | `<T>(t1: T, t2: T) => number` | Generic comparison function | `useCompare("a", "b")` → `-1` |
|
|
73
|
+
| `useRandom` | `<T = number\|bigint>(index: T) => T` | Pseudorandom number generator | `useRandom(5)` → random number |
|
|
73
74
|
|
|
74
|
-
|
|
75
|
+
**Code Example Supplement:**
|
|
76
|
+
```typescript
|
|
77
|
+
import { validate, invalidate, useCompare, useRandom } from 'semantic-typescript';
|
|
75
78
|
|
|
76
|
-
|
|
79
|
+
// Validate data validity
|
|
80
|
+
const data: string | null = "hello";
|
|
81
|
+
if (validate(data)) {
|
|
82
|
+
console.log(data.toUpperCase()); // Safe call because validate ensures data is not null
|
|
83
|
+
}
|
|
77
84
|
|
|
78
|
-
|
|
85
|
+
const nullData: string | null = null;
|
|
86
|
+
if (invalidate(nullData)) {
|
|
87
|
+
console.log("Data invalid"); // Will execute because invalidate detected null
|
|
88
|
+
}
|
|
79
89
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
| `from(iterable)` | Create from Array/Set/Iterable | `from([1, 2, 3])` |
|
|
83
|
-
| `range(start, end, step?)` | Generate number range | `range(0, 5)` → 0,1,2,3,4 |
|
|
84
|
-
| `fill(element, count)` | Repeat an element N times | `fill('a', 3n)` |
|
|
85
|
-
| `iterate(gen)` | Use a custom generator function | `iterate(genFn)` |
|
|
90
|
+
// Compare values
|
|
91
|
+
const comparison = useCompare("apple", "banana"); // -1
|
|
86
92
|
|
|
87
|
-
|
|
93
|
+
// Generate random number
|
|
94
|
+
const randomNum = useRandom(42); // Random number based on seed 42
|
|
95
|
+
```
|
|
88
96
|
|
|
89
|
-
|
|
90
|
-
|--------------------|---------------------------------------------------|---------|
|
|
91
|
-
| `map(fn)` | Transform each element | `.map(x => x * 2)` |
|
|
92
|
-
| `filter(fn)` | Retain elements passing predicate | `.filter(x => x > 10)` |
|
|
93
|
-
| `limit(n)` | Limit to first N elements | `.limit(5)` |
|
|
94
|
-
| `skip(n)` | Skip first N elements | `.skip(2)` |
|
|
95
|
-
| `distinct()` | Remove duplicates (uses Set by default) | `.distinct()` |
|
|
96
|
-
| `sorted()` | Sort elements (natural ordering) | `.sorted()` |
|
|
97
|
-
| `sorted(comparator)`| Custom sorting | `.sorted((a, b) => a - b)` |
|
|
98
|
-
| `toOrdered()` | Sort and return `OrderedCollectable` | `.toOrdered()` |
|
|
99
|
-
| `toUnordered()` | **No sorting** – fastest possible collectable | `.toUnordered()` ✅ |
|
|
100
|
-
| `collect(collector)`| Aggregate using a `Collector` | `.collect(Collector.full(...))` |
|
|
101
|
-
| `toArray()` | Convert to Array | `.toArray()` |
|
|
102
|
-
| `toSet()` | Convert to Set | `.toSet()` |
|
|
103
|
-
| `toMap(keyFn, valFn)`| Convert to Map | `.toMap(x => x.id, x => x)` |
|
|
97
|
+
## Core Class Details
|
|
104
98
|
|
|
105
|
-
|
|
99
|
+
### Optional<T> - Safe Null Value Handling
|
|
106
100
|
|
|
107
|
-
|
|
101
|
+
The Optional class provides a functional approach to safely handle values that may be null or undefined.
|
|
108
102
|
|
|
109
|
-
|
|
103
|
+
| Method | Return Type | Description | Time Complexity |
|
|
104
|
+
|------|----------|------|------------|
|
|
105
|
+
| `filter(predicate: Predicate<T>)` | `Optional<T>` | Filter values satisfying condition | O(1) |
|
|
106
|
+
| `get()` | `T` | Get value, throw error if empty | O(1) |
|
|
107
|
+
| `getOrDefault(defaultValue: T)` | `T` | Get value or default value | O(1) |
|
|
108
|
+
| `ifPresent(action: Consumer<T>)` | `void` | Execute action if value exists | O(1) |
|
|
109
|
+
| `isEmpty()` | `boolean` | Check if empty | O(1) |
|
|
110
|
+
| `isPresent()` | `boolean` | Check if value exists | O(1) |
|
|
111
|
+
| `map<R>(mapper: Functional<T, R>)` | `Optional<R>` | Map and transform value | O(1) |
|
|
112
|
+
| `static of<T>(value: MaybeInvalid<T>)` | `Optional<T>` | Create Optional instance | O(1) |
|
|
113
|
+
| `static ofNullable<T>(value?)` | `Optional<T>` | Create nullable Optional | O(1) |
|
|
114
|
+
| `static ofNonNull<T>(value: T)` | `Optional<T>` | Create non-null Optional | O(1) |
|
|
110
115
|
|
|
116
|
+
**Code Example Supplement:**
|
|
111
117
|
```typescript
|
|
112
|
-
|
|
113
|
-
```
|
|
118
|
+
import { Optional } from 'semantic-typescript';
|
|
114
119
|
|
|
115
|
-
|
|
116
|
-
|
|
120
|
+
// Create Optional instance
|
|
121
|
+
const optionalValue = Optional.ofNullable<string>(Math.random() > 0.5 ? "hello" : null);
|
|
117
122
|
|
|
118
|
-
|
|
123
|
+
// Chain operations
|
|
124
|
+
const result = optionalValue
|
|
125
|
+
.filter(val => val.length > 3) // Filter values longer than 3
|
|
126
|
+
.map(val => val.toUpperCase()) // Convert to uppercase
|
|
127
|
+
.getOrDefault("default"); // Get value or default
|
|
119
128
|
|
|
120
|
-
|
|
129
|
+
console.log(result); // "HELLO" or "default"
|
|
121
130
|
|
|
122
|
-
|
|
131
|
+
// Safe operations
|
|
132
|
+
optionalValue.ifPresent(val => {
|
|
133
|
+
console.log(`Value exists: ${val}`);
|
|
134
|
+
});
|
|
123
135
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
136
|
+
// Check status
|
|
137
|
+
if (optionalValue.isPresent()) {
|
|
138
|
+
console.log("Has value");
|
|
139
|
+
} else if (optionalValue.isEmpty()) {
|
|
140
|
+
console.log("Is empty");
|
|
141
|
+
}
|
|
128
142
|
```
|
|
129
143
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
144
|
+
### Semantic<E> - Lazy Data Stream
|
|
145
|
+
|
|
146
|
+
Semantic is the core stream processing class, providing rich stream operators.
|
|
147
|
+
|
|
148
|
+
#### Stream Transformation Operations
|
|
149
|
+
|
|
150
|
+
| Method | Return Type | Description | Performance Impact |
|
|
151
|
+
|------|----------|------|----------|
|
|
152
|
+
| `concat(other: Semantic<E>)` | `Semantic<E>` | Concatenate two streams | O(n+m) |
|
|
153
|
+
| `distinct()` | `Semantic<E>` | Remove duplicates (using Set) | O(n) |
|
|
154
|
+
| `distinct(comparator)` | `Semantic<E>` | Custom comparator deduplication | O(n²) |
|
|
155
|
+
| `dropWhile(predicate)` | `Semantic<E>` | Discard starting elements satisfying condition | O(n) |
|
|
156
|
+
| `filter(predicate)` | `Semantic<E>` | Filter elements | O(n) |
|
|
157
|
+
| `flat(mapper)` | `Semantic<E>` | Flatten nested streams | O(n×m) |
|
|
158
|
+
| `flatMap(mapper)` | `Semantic<R>` | Map and flatten | O(n×m) |
|
|
159
|
+
| `limit(n)` | `Semantic<E>` | Limit number of elements | O(n) |
|
|
160
|
+
| `map(mapper)` | `Semantic<R>` | Map and transform elements | O(n) |
|
|
161
|
+
| `peek(consumer)` | `Semantic<E>` | View elements without modification | O(n) |
|
|
162
|
+
| `redirect(redirector)` | `Semantic<E>` | Redirect indices | O(n) |
|
|
163
|
+
| `reverse()` | `Semantic<E>` | Reverse stream order | O(n) |
|
|
164
|
+
| `shuffle()` | `Semantic<E>` | Randomly shuffle order | O(n) |
|
|
165
|
+
| `shuffle(mapper)` | `Semantic<E>` | Custom shuffle logic | O(n) |
|
|
166
|
+
| `skip(n)` | `Semantic<E>` | Skip first n elements | O(n) |
|
|
167
|
+
| `sub(start, end)` | `Semantic<E>` | Get substream | O(n) |
|
|
168
|
+
| `takeWhile(predicate)` | `Semantic<E>` | Get starting elements satisfying condition | O(n) |
|
|
169
|
+
| `translate(offset)` | `Semantic<E>` | Translate indices | O(n) |
|
|
170
|
+
| `translate(translator)` | `Semantic<E>` | Custom index transformation | O(n) |
|
|
171
|
+
|
|
172
|
+
**Code Example Supplement:**
|
|
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
|
+
// Stream transformation operation examples
|
|
179
|
+
const processedStream = stream
|
|
180
|
+
.filter(x => x % 2 === 0) // Filter even numbers
|
|
181
|
+
.map(x => x * 2) // Multiply each element by 2
|
|
182
|
+
.distinct() // Remove duplicates
|
|
183
|
+
.limit(3) // Limit to first 3 elements
|
|
184
|
+
.peek((val, index) => console.log(`Element ${val} at index ${index}`)); // View elements
|
|
139
185
|
|
|
140
|
-
|
|
141
|
-
Collector.full(identity, accumulator, finisher)
|
|
142
|
-
Collector.shortable(identity, interruptor, accumulator, finisher)
|
|
186
|
+
// Note: The stream hasn't executed yet, needs conversion to Collectable for terminal operations
|
|
143
187
|
```
|
|
144
188
|
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
---
|
|
189
|
+
#### Stream Terminal Operations
|
|
148
190
|
|
|
149
|
-
|
|
191
|
+
| Method | Return Type | Description | Performance Characteristics |
|
|
192
|
+
|------|----------|------|----------|
|
|
193
|
+
| `toOrdered()` | `OrderedCollectable<E>` | Convert to ordered collection | Sorting operation, lower performance |
|
|
194
|
+
| `toUnordered()` | `UnorderedCollectable<E>` | Convert to unordered collection | Fastest, no sorting |
|
|
195
|
+
| `toWindow()` | `WindowCollectable<E>` | Convert to window collection | Sorting operation, lower performance |
|
|
196
|
+
| `toNumericStatistics()` | `Statistics<E, number>` | Numerical statistical analysis | Sorting operation, lower performance |
|
|
197
|
+
| `toBigintStatistics()` | `Statistics<E, bigint>` | Big integer statistical analysis | Sorting operation, lower performance |
|
|
198
|
+
| `sorted()` | `OrderedCollectable<E>` | Natural sorting | Overrides redirection results |
|
|
199
|
+
| `sorted(comparator)` | `OrderedCollectable<E>` | Custom sorting | Overrides redirection results |
|
|
150
200
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
- `UnorderedCollectable<E>` – No sorting, fastest
|
|
155
|
-
- `WindowCollectable<E>` – Sliding windows
|
|
156
|
-
- `Statistics<E, D>` – Statistical aggregations
|
|
201
|
+
**Code Example Supplement:**
|
|
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 elements | `.count()` |
|
|
163
|
-
| `toArray()` | Convert to Array | `.toArray()` |
|
|
164
|
-
| `toSet()` | Convert to Set | `.toSet()` |
|
|
165
|
-
| `toMap(k, v)` | Convert to Map | `.toMap(x => x.id, x => x)` |
|
|
166
|
-
| `group(k)` | Group by key | `.group(x => x.category)` |
|
|
167
|
-
| `findAny()` | Any matching element (Optional) | `.findAny()` |
|
|
168
|
-
| `findFirst()` | First element (Optional) | `.findFirst()` |
|
|
169
|
-
| `reduce(...)` | Custom reduction | `.reduce((a,b) => a + b, 0)` |
|
|
207
|
+
// Convert to ordered collection (lower performance)
|
|
208
|
+
const ordered = semanticStream.toOrdered();
|
|
170
209
|
|
|
171
|
-
|
|
210
|
+
// Convert to unordered collection (fastest)
|
|
211
|
+
const unordered = semanticStream.toUnordered();
|
|
172
212
|
|
|
173
|
-
|
|
213
|
+
// Natural sorting
|
|
214
|
+
const sortedNatural = semanticStream.sorted();
|
|
174
215
|
|
|
175
|
-
|
|
216
|
+
// Custom sorting
|
|
217
|
+
const sortedCustom = semanticStream.sorted((a, b) => b - a); // Descending sort
|
|
176
218
|
|
|
177
|
-
|
|
219
|
+
// Convert to statistical object
|
|
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
|
+
// Note: Must call above methods through Semantic instance to get Collectable before using terminal methods
|
|
182
223
|
```
|
|
183
224
|
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
---
|
|
225
|
+
### Collector<E, A, R> - Data Collector
|
|
187
226
|
|
|
188
|
-
|
|
227
|
+
Collectors are used to aggregate stream data into specific structures.
|
|
189
228
|
|
|
190
|
-
|
|
229
|
+
| Method | Description | Usage Scenario |
|
|
230
|
+
|------|------|----------|
|
|
231
|
+
| `collect(generator)` | Execute data collection | Stream terminal operation |
|
|
232
|
+
| `static full(identity, accumulator, finisher)` | Create complete collector | Requires complete processing |
|
|
233
|
+
| `static shortable(identity, interruptor, accumulator, finisher)` | Create interruptible collector | May terminate early |
|
|
191
234
|
|
|
235
|
+
**Code Example Supplement:**
|
|
192
236
|
```typescript
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
237
|
+
import { Collector } from 'semantic-typescript';
|
|
238
|
+
|
|
239
|
+
// Create custom collector
|
|
240
|
+
const sumCollector = Collector.full(
|
|
241
|
+
() => 0, // Initial value
|
|
242
|
+
(acc, value) => acc + value, // Accumulator
|
|
243
|
+
result => result // Finisher function
|
|
244
|
+
);
|
|
245
|
+
|
|
246
|
+
// Use collector (requires conversion from Semantic to Collectable first)
|
|
247
|
+
const numbers = from([1, 2, 3, 4, 5]);
|
|
248
|
+
const sum = numbers.toUnordered().collect(sumCollector); // 15
|
|
196
249
|
```
|
|
197
250
|
|
|
198
|
-
|
|
199
|
-
✅ **Best performance** when order is irrelevant
|
|
200
|
-
|
|
201
|
-
---
|
|
251
|
+
### Collectable<E> - Collectable Data Abstract Class
|
|
202
252
|
|
|
203
|
-
|
|
253
|
+
Provides rich data aggregation and transformation methods. **Note: Must first obtain Collectable instance by calling sorted(), toOrdered() etc. through Semantic instance before using the following methods.**
|
|
204
254
|
|
|
205
|
-
|
|
255
|
+
#### Data Query Operations
|
|
206
256
|
|
|
207
|
-
|
|
257
|
+
| Method | Return Type | Description | Example |
|
|
258
|
+
|------|----------|------|------|
|
|
259
|
+
| `anyMatch(predicate)` | `boolean` | Whether any element matches | `anyMatch(x => x > 0)` |
|
|
260
|
+
| `allMatch(predicate)` | `boolean` | Whether all elements match | `allMatch(x => x > 0)` |
|
|
261
|
+
| `count()` | `bigint` | Element count statistics | `count()` → `5n` |
|
|
262
|
+
| `isEmpty()` | `boolean` | Whether stream is empty | `isEmpty()` |
|
|
263
|
+
| `findAny()` | `Optional<E>` | Find any element | `findAny()` |
|
|
264
|
+
| `findFirst()` | `Optional<E>` | Find first element | `findFirst()` |
|
|
265
|
+
| `findLast()` | `Optional<E>` | Find last element | `findLast()` |
|
|
208
266
|
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
##### Common statistical methods:
|
|
267
|
+
**Code Example Supplement:**
|
|
268
|
+
```typescript
|
|
269
|
+
import { from } from 'semantic-typescript';
|
|
213
270
|
|
|
214
|
-
|
|
215
|
-
|-------------------|--------------------------------------|---------|
|
|
216
|
-
| `mean()` | Arithmetic mean | `.mean()` |
|
|
217
|
-
| `median()` | Median value | `.median()` |
|
|
218
|
-
| `mode()` | Most frequent value | `.mode()` |
|
|
219
|
-
| `minimum()` | Smallest element | `.minimum()` |
|
|
220
|
-
| `maximum()` | Largest element | `.maximum()` |
|
|
221
|
-
| `range()` | Maximum − Minimum | `.range()` |
|
|
222
|
-
| `variance()` | Variance | `.variance()` |
|
|
223
|
-
| `standardDeviation()` | Standard deviation | `.standardDeviation()` |
|
|
224
|
-
| `summate()` | Sum of elements | `.summate()` |
|
|
225
|
-
| `quantile(q)` | Value at q-th percentile (0–1) | `.quantile(0.5)` → median |
|
|
226
|
-
| `frequency()` | Frequency map | `.frequency()` |
|
|
271
|
+
const numbers = from([1, 2, 3, 4, 5]);
|
|
227
272
|
|
|
228
|
-
|
|
273
|
+
// Must convert to Collectable before using terminal methods
|
|
274
|
+
const collectable = numbers.toUnordered();
|
|
229
275
|
|
|
230
|
-
|
|
276
|
+
// Data query operations
|
|
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(); // Any element
|
|
283
|
+
```
|
|
231
284
|
|
|
285
|
+
#### Data Aggregation Operations
|
|
286
|
+
|
|
287
|
+
| Method | Return Type | Description | Complexity |
|
|
288
|
+
|------|----------|------|--------|
|
|
289
|
+
| `group(classifier)` | `Map<K, E[]>` | Group by classifier | O(n) |
|
|
290
|
+
| `groupBy(keyExtractor, valueExtractor)` | `Map<K, V[]>` | Group by key-value extractors | O(n) |
|
|
291
|
+
| `join()` | `string` | Join as string | O(n) |
|
|
292
|
+
| `join(delimiter)` | `string` | Join with delimiter | O(n) |
|
|
293
|
+
| `partition(count)` | `E[][]` | Partition by count | O(n) |
|
|
294
|
+
| `partitionBy(classifier)` | `E[][]` | Partition by classifier | O(n) |
|
|
295
|
+
| `reduce(accumulator)` | `Optional<E>` | Reduction operation | O(n) |
|
|
296
|
+
| `reduce(identity, accumulator)` | `E` | Reduction with identity | O(n) |
|
|
297
|
+
| `toArray()` | `E[]` | Convert to array | O(n) |
|
|
298
|
+
| `toMap(keyExtractor, valueExtractor)` | `Map<K, V>` | Convert to Map | O(n) |
|
|
299
|
+
| `toSet()` | `Set<E>` | Convert to Set | O(n) |
|
|
300
|
+
|
|
301
|
+
**Code Example Supplement:**
|
|
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
|
+
// Must convert to Collectable before using aggregation operations
|
|
312
|
+
const collectable = people.toUnordered();
|
|
313
|
+
|
|
314
|
+
// Grouping operations
|
|
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
|
+
// Convert to collections
|
|
325
|
+
const array = collectable.toArray(); // Original array
|
|
326
|
+
const set = collectable.toSet(); // Set collection
|
|
327
|
+
const map = collectable.toMap(
|
|
328
|
+
person => person.name,
|
|
329
|
+
person => person.age
|
|
330
|
+
); // Map { "Alice" => 25, "Bob" => 30, "Charlie" => 25 }
|
|
331
|
+
|
|
332
|
+
// Reduction operations
|
|
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
|
+
### Specific Collector Implementations
|
|
256
338
|
|
|
257
|
-
|
|
339
|
+
#### UnorderedCollectable<E>
|
|
340
|
+
- **Characteristics**: Fastest collector, no sorting
|
|
341
|
+
- **Usage Scenarios**: Order unimportant, maximum performance desired
|
|
342
|
+
- **Methods**: Inherits all Collectable methods
|
|
258
343
|
|
|
259
|
-
|
|
344
|
+
#### OrderedCollectable<E>
|
|
345
|
+
- **Characteristics**: Guarantees element order, lower performance
|
|
346
|
+
- **Usage Scenarios**: Require sorted results
|
|
347
|
+
- **Special Methods**: Inherits all methods, maintains internal sort state
|
|
260
348
|
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
| `useCompare(a, b)`| Universal comparison function |
|
|
268
|
-
| `useRandom(x)` | Pseudo-random generator (fun) |
|
|
349
|
+
#### WindowCollectable<E>
|
|
350
|
+
- **Characteristics**: Supports sliding window operations
|
|
351
|
+
- **Usage Scenarios**: Time series data analysis
|
|
352
|
+
- **Special Methods**:
|
|
353
|
+
- `slide(size, step)` - Sliding window
|
|
354
|
+
- `tumble(size)` - Tumbling window
|
|
269
355
|
|
|
270
|
-
|
|
356
|
+
**Code Example Supplement:**
|
|
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
|
+
// Unordered collector (fastest)
|
|
363
|
+
const unordered = data.toUnordered();
|
|
364
|
+
const unorderedArray = unordered.toArray(); // May maintain original order [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
|
+
// Ordered collector
|
|
367
|
+
const ordered = data.toOrdered();
|
|
368
|
+
const orderedArray = ordered.toArray(); // Guaranteed sorted [1, 2, 3, ...]
|
|
286
369
|
|
|
287
|
-
|
|
370
|
+
// Window collector
|
|
371
|
+
const windowed = data.toWindow();
|
|
372
|
+
const slidingWindows = windowed.slide(3n, 2n); // Window size 3, step 2
|
|
373
|
+
// Window 1: [1, 2, 3], Window 2: [3, 4, 5], Window 3: [5, 6, 7], ...
|
|
288
374
|
|
|
289
|
-
|
|
290
|
-
|
|
375
|
+
const tumblingWindows = windowed.tumble(4n); // Tumbling window size 4
|
|
376
|
+
// Window 1: [1, 2, 3, 4], Window 2: [5, 6, 7, 8], ...
|
|
291
377
|
```
|
|
292
378
|
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
379
|
+
### Statistics<E, D> - Statistical Analysis
|
|
380
|
+
|
|
381
|
+
Statistical analysis base class providing rich statistical calculation methods. **Note: Must first obtain Statistics instance by calling toNumericStatistics() or toBigIntStatistics() through Semantic instance before using the following methods.**
|
|
382
|
+
|
|
383
|
+
#### Statistical Calculation Operations
|
|
384
|
+
|
|
385
|
+
| Method | Return Type | Description | Algorithm Complexity |
|
|
386
|
+
|------|----------|------|------------|
|
|
387
|
+
| `maximum()` | `Optional<E>` | Maximum value | O(n) |
|
|
388
|
+
| `minimum()` | `Optional<E>` | Minimum value | O(n) |
|
|
389
|
+
| `range()` | `D` | Range (max-min) | O(n) |
|
|
390
|
+
| `variance()` | `D` | Variance | O(n) |
|
|
391
|
+
| `standardDeviation()` | `D` | Standard deviation | O(n) |
|
|
392
|
+
| `mean()` | `D` | Mean value | O(n) |
|
|
393
|
+
| `median()` | `D` | Median value | O(n log n) |
|
|
394
|
+
| `mode()` | `D` | Mode value | O(n) |
|
|
395
|
+
| `frequency()` | `Map<D, bigint>` | Frequency distribution | O(n) |
|
|
396
|
+
| `summate()` | `D` | Summation | O(n) |
|
|
397
|
+
| `quantile(quantile)` | `D` | Quantile | O(n log n) |
|
|
398
|
+
| `interquartileRange()` | `D` | Interquartile range | O(n log n) |
|
|
399
|
+
| `skewness()` | `D` | Skewness | O(n) |
|
|
400
|
+
| `kurtosis()` | `D` | Kurtosis | O(n) |
|
|
401
|
+
|
|
402
|
+
**Code Example Supplement:**
|
|
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
|
+
// Must convert to statistical object before using statistical methods
|
|
409
|
+
const stats = numbers.toNumericStatistics();
|
|
410
|
+
|
|
411
|
+
// Basic statistics
|
|
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
|
+
// Advanced statistics
|
|
421
|
+
const variance = stats.variance(); // 8.25
|
|
422
|
+
const stdDev = stats.standardDeviation(); // 2.872
|
|
423
|
+
const mode = stats.mode(); // Any value (since all appear once)
|
|
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
|
+
// Frequency distribution
|
|
429
|
+
const freq = stats.frequency(); // Map {1 => 1n, 2 => 1n, ...}
|
|
430
|
+
```
|
|
298
431
|
|
|
299
|
-
|
|
432
|
+
#### Specific Statistical Implementation Classes
|
|
300
433
|
|
|
301
|
-
|
|
434
|
+
**NumericStatistics<E>**
|
|
435
|
+
- Handles number type statistical analysis
|
|
436
|
+
- All statistical calculations return number type
|
|
302
437
|
|
|
303
|
-
|
|
438
|
+
**BigIntStatistics<E>**
|
|
439
|
+
- Handles bigint type statistical analysis
|
|
440
|
+
- All statistical calculations return bigint type
|
|
304
441
|
|
|
305
|
-
|
|
442
|
+
**Code Example Supplement:**
|
|
443
|
+
```typescript
|
|
444
|
+
import { from } from 'semantic-typescript';
|
|
306
445
|
|
|
307
|
-
|
|
446
|
+
// Numerical statistics
|
|
447
|
+
const numberData = from([10, 20, 30, 40, 50]);
|
|
448
|
+
const numericStats = numberData.toNumericStatistics();
|
|
308
449
|
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
| Safely handle nulls | `Optional<T>` |
|
|
312
|
-
| Create a stream | `from([...])`, `range()`, `fill()` |
|
|
313
|
-
| Transform data | `map()`, `filter()` |
|
|
314
|
-
| Sort data | `sorted()`, `toOrdered()` |
|
|
315
|
-
| No sort (fastest) | `toUnordered()` ✅ |
|
|
316
|
-
| Group / aggregate | `toMap()`, `group()`, `Collector` |
|
|
317
|
-
| Statistics | `NumericStatistics`, `mean()`, `median()`, etc. |
|
|
450
|
+
console.log(numericStats.mean()); // 30
|
|
451
|
+
console.log(numericStats.summate()); // 150
|
|
318
452
|
|
|
319
|
-
|
|
453
|
+
// Big integer statistics
|
|
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
|
+
// Statistics using mapper functions
|
|
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
|
+
## Complete Usage Example
|
|
330
474
|
|
|
331
|
-
|
|
475
|
+
```typescript
|
|
476
|
+
import { from, validate, invalidate } from 'semantic-typescript';
|
|
477
|
+
|
|
478
|
+
// 1. Create data stream
|
|
479
|
+
const rawData = [5, 2, 8, 1, null, 9, 3, undefined, 7, 4, 6];
|
|
480
|
+
const semanticStream = from(rawData);
|
|
481
|
+
|
|
482
|
+
// 2. Stream processing pipeline
|
|
483
|
+
const processedStream = semanticStream
|
|
484
|
+
.filter(val => validate(val)) // Filter out null and undefined
|
|
485
|
+
.map(val => val! * 2) // Multiply each value by 2 (using ! because validate ensures not empty)
|
|
486
|
+
.distinct(); // Remove duplicates
|
|
487
|
+
|
|
488
|
+
// 3. Convert to Collectable and use terminal operations
|
|
489
|
+
const collectable = processedStream.toUnordered();
|
|
490
|
+
|
|
491
|
+
// 4. Data validation and usage
|
|
492
|
+
if (!collectable.isEmpty()) {
|
|
493
|
+
const results = collectable
|
|
494
|
+
.filter(x => x > 5) // Filter again
|
|
495
|
+
.toArray(); // Convert to array
|
|
496
|
+
|
|
497
|
+
console.log("Processing results:", results); // [16, 18, 14, 8, 12]
|
|
498
|
+
|
|
499
|
+
// Statistical information
|
|
500
|
+
const stats = processedStream.toNumericStatistics();
|
|
501
|
+
console.log("Mean value:", stats.mean()); // 11.2
|
|
502
|
+
console.log("Total sum:", stats.summate()); // 56
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
// 5. Handle potentially invalid data
|
|
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("Valid data:", validData); // [1, 3, 4]
|
|
511
|
+
console.log("Invalid data:", invalidData); // [null, null]
|
|
512
|
+
```
|
|
332
513
|
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
514
|
+
## Important Usage Rules Summary
|
|
515
|
+
|
|
516
|
+
1. **Create Stream**: Use `from()`, `range()`, `fill()` etc. factory methods to create Semantic instances
|
|
517
|
+
2. **Stream Transformation**: Call `map()`, `filter()`, `distinct()` etc. methods on Semantic instances
|
|
518
|
+
3. **Convert to Collectable**: Must call one of the following methods through Semantic instance:
|
|
519
|
+
- `toOrdered()` - Ordered collector
|
|
520
|
+
- `toUnordered()` - Unordered collector (fastest)
|
|
521
|
+
- `toWindow()` - Window collector
|
|
522
|
+
- `toNumericStatistics()` - Numerical statistics
|
|
523
|
+
- `toBigIntStatistics()` - Big integer statistics
|
|
524
|
+
- `sorted()` - Natural sorting
|
|
525
|
+
- `sorted(comparator)` - Custom sorting
|
|
526
|
+
4. **Terminal Operations**: Call `toArray()`, `count()`, `summate()` etc. terminal methods on Collectable instances
|
|
527
|
+
5. **Data Validation**: Use `validate()` to ensure data is not null/undefined, use `invalidate()` to check invalid data
|
|
528
|
+
|
|
529
|
+
This design ensures type safety and performance optimisation while providing rich stream processing functionality.
|