semantic-typescript 0.0.6 → 0.0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/semantic.d.ts +8 -1
- package/dist/semantic.js +161 -9
- package/package.json +2 -2
- package/readme.cn.md +441 -247
- package/readme.de.md +434 -240
- package/readme.es.md +434 -240
- package/readme.fr.md +434 -240
- package/readme.jp.md +434 -240
- package/readme.kr.md +529 -0
- package/readme.md +434 -240
- package/readme.ru.md +529 -0
- package/readme.tw.md +441 -247
- package/readme.ko.md +0 -335
package/readme.ru.md
ADDED
|
@@ -0,0 +1,529 @@
|
|
|
1
|
+
# Фреймворк для потоковой обработки Semantic-TypeScript
|
|
2
|
+
|
|
3
|
+
## Введение
|
|
4
|
+
|
|
5
|
+
Semantic-TypeScript — это современная библиотека для потоковой обработки данных, вдохновленная JavaScript GeneratorFunction, Java Stream и MySQL Index. Основная философия дизайна основана на построении эффективных конвейеров обработки данных через индексацию данных, предоставляя типобезопасный, функциональный опыт потоковых операций для фронтенд-разработки.
|
|
6
|
+
|
|
7
|
+
В отличие от традиционной синхронной обработки, Semantic использует асинхронную модель обработки. При создании потоков данных время получения терминальных данных полностью зависит от того, когда вышестоящий код вызовет функции обратного вызова `accept` и `interrupt`. Этот дизайн позволяет библиотеке изящно обрабатывать потоки данных в реальном времени, большие наборы данных и асинхронные источники данных.
|
|
8
|
+
|
|
9
|
+
## Основные возможности
|
|
10
|
+
|
|
11
|
+
| Возможность | Описание | Преимущество |
|
|
12
|
+
|------|------|------|
|
|
13
|
+
| **Типобезопасные дженерики** | Полная поддержка типов TypeScript | Обнаружение ошибок на этапе компиляции, лучший опыт разработки |
|
|
14
|
+
| **Функциональное программирование** | Неизменяемые структуры данных и чистые функции | Более предсказуемый код, легкое тестирование и сопровождение |
|
|
15
|
+
| **Ленивые вычисления** | Вычисления по требованию, оптимизация производительности | Высокая эффективность использования памяти при обработке больших наборов данных |
|
|
16
|
+
| **Асинхронная потоковая обработка** | Асинхронные потоки данных на основе генераторов | Подходит для сценариев с данными в реальном времени и событийно-ориентированных сценариев |
|
|
17
|
+
| **Мультипарадигменные коллекторы** | Стратегии сбора с упорядочиванием, без упорядочивания, статистические | Выбор оптимальной стратегии на основе разных сценариев |
|
|
18
|
+
| **Статистический анализ** | Встроенные полные функции статистических вычислений | Интегрированный анализ данных и генерация отчетов |
|
|
19
|
+
|
|
20
|
+
## Соображения производительности
|
|
21
|
+
|
|
22
|
+
**Важное примечание**: Следующие методы жертвуют производительностью для сбора и сортировки данных, что приводит к упорядоченным коллекциям данных:
|
|
23
|
+
- `toOrdered()`
|
|
24
|
+
- `toWindow()`
|
|
25
|
+
- `toNumericStatistics()`
|
|
26
|
+
- `toBigIntStatistics()`
|
|
27
|
+
- `sorted()`
|
|
28
|
+
- `sorted(comparator)`
|
|
29
|
+
|
|
30
|
+
Особенно важно отметить: `sorted()` и `sorted(comparator)` переопределяют результаты следующих методов:
|
|
31
|
+
- `redirect(redirector)`
|
|
32
|
+
- `translate(translator)`
|
|
33
|
+
- `shuffle(mapper)`
|
|
34
|
+
|
|
35
|
+
## Фабричные методы
|
|
36
|
+
|
|
37
|
+
### Фабрики создания потоков
|
|
38
|
+
|
|
39
|
+
| Метод | Сигнатура | Описание | Пример |
|
|
40
|
+
|------|------|------|------|
|
|
41
|
+
| `blob` | `(blob: Blob, chunk?: bigint) => Semantic<Uint8Array>` | Преобразовать Blob в поток байтов | `blob(fileBlob, 1024n)` |
|
|
42
|
+
| `empty` | `<E>() => Semantic<E>` | Создать пустой поток | `empty<number>()` |
|
|
43
|
+
| `fill` | `<E>(element: E, count: bigint) => Semantic<E>` | Заполнить указанным количеством элементов | `fill("hello", 5n)` |
|
|
44
|
+
| `from` | `<E>(iterable: Iterable<E>) => Semantic<E>` | Создать поток из итерируемого объекта | `from([1, 2, 3])` |
|
|
45
|
+
| `range` | `<N extends number\|bigint>(start: N, end: N, step?: N) => Semantic<N>` | Создать поток числового диапазона | `range(1, 10, 2)` |
|
|
46
|
+
| `iterate` | `<E>(generator: Generator<E>) => Semantic<E>` | Создать поток из функции-генератора | `iterate(myGenerator)` |
|
|
47
|
+
| `websocket` | `(websocket: WebSocket) => Semantic<MessageEvent>` | Создать поток событий из WebSocket | `websocket(socket)` |
|
|
48
|
+
|
|
49
|
+
**Дополнение с примером кода:**
|
|
50
|
+
```typescript
|
|
51
|
+
import { from, range, fill, empty } from 'semantic-typescript';
|
|
52
|
+
|
|
53
|
+
// Создать поток из массива
|
|
54
|
+
const numberStream = from([1, 2, 3, 4, 5]);
|
|
55
|
+
|
|
56
|
+
// Создать поток числового диапазона
|
|
57
|
+
const rangeStream = range(1, 10, 2); // 1, 3, 5, 7, 9
|
|
58
|
+
|
|
59
|
+
// Заполнить повторяющимися элементами
|
|
60
|
+
const filledStream = fill("hello", 3n); // "hello", "hello", "hello"
|
|
61
|
+
|
|
62
|
+
// Создать пустой поток
|
|
63
|
+
const emptyStream = empty<number>();
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### Фабрики служебных функций
|
|
67
|
+
|
|
68
|
+
| Метод | Сигнатура | Описание | Пример |
|
|
69
|
+
|------|------|------|------|
|
|
70
|
+
| `validate` | `<T>(t: MaybeInvalid<T>) => t is T` | Проверить, является ли значение валидным | `validate(null)` → `false` |
|
|
71
|
+
| `invalidate` | `<T>(t: MaybeInvalid<T>) => t is null\|undefined` | Проверить, является ли значение невалидным | `invalidate(0)` → `false` |
|
|
72
|
+
| `useCompare` | `<T>(t1: T, t2: T) => number` | Универсальная функция сравнения | `useCompare("a", "b")` → `-1` |
|
|
73
|
+
| `useRandom` | `<T = number\|bigint>(index: T) => T` | Генератор псевдослучайных чисел | `useRandom(5)` → случайное число |
|
|
74
|
+
|
|
75
|
+
**Дополнение с примером кода:**
|
|
76
|
+
```typescript
|
|
77
|
+
import { validate, invalidate, useCompare, useRandom } from 'semantic-typescript';
|
|
78
|
+
|
|
79
|
+
// Проверить валидность данных
|
|
80
|
+
const data: string | null = "hello";
|
|
81
|
+
if (validate(data)) {
|
|
82
|
+
console.log(data.toUpperCase()); // Безопасный вызов, так как validate гарантирует, что data не null
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
const nullData: string | null = null;
|
|
86
|
+
if (invalidate(nullData)) {
|
|
87
|
+
console.log("Данные невалидны"); // Выполнится, потому что invalidate обнаружил null
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// Сравнить значения
|
|
91
|
+
const comparison = useCompare("apple", "banana"); // -1
|
|
92
|
+
|
|
93
|
+
// Сгенерировать случайное число
|
|
94
|
+
const randomNum = useRandom(42); // Случайное число на основе сида 42
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
## Детали основного класса
|
|
98
|
+
|
|
99
|
+
### Optional<T> - Безопасная обработка нулевых значений
|
|
100
|
+
|
|
101
|
+
Класс Optional предоставляет функциональный подход для безопасной обработки значений, которые могут быть null или undefined.
|
|
102
|
+
|
|
103
|
+
| Метод | Тип возврата | Описание | Сложность по времени |
|
|
104
|
+
|------|----------|------|------------|
|
|
105
|
+
| `filter(predicate: Predicate<T>)` | `Optional<T>` | Отфильтровать значения, удовлетворяющие условию | O(1) |
|
|
106
|
+
| `get()` | `T` | Получить значение, выбросить ошибку если пустое | O(1) |
|
|
107
|
+
| `getOrDefault(defaultValue: T)` | `T` | Получить значение или значение по умолчанию | O(1) |
|
|
108
|
+
| `ifPresent(action: Consumer<T>)` | `void` | Выполнить действие, если значение существует | O(1) |
|
|
109
|
+
| `isEmpty()` | `boolean` | Проверить, пусто ли | O(1) |
|
|
110
|
+
| `isPresent()` | `boolean` | Проверить, существует ли значение | O(1) |
|
|
111
|
+
| `map<R>(mapper: Functional<T, R>)` | `Optional<R>` | Отобразить и преобразовать значение | O(1) |
|
|
112
|
+
| `static of<T>(value: MaybeInvalid<T>)` | `Optional<T>` | Создать экземпляр Optional | O(1) |
|
|
113
|
+
| `static ofNullable<T>(value?)` | `Optional<T>` | Создать nullable Optional | O(1) |
|
|
114
|
+
| `static ofNonNull<T>(value: T)` | `Optional<T>` | Создать не-null Optional | O(1) |
|
|
115
|
+
|
|
116
|
+
**Дополнение с примером кода:**
|
|
117
|
+
```typescript
|
|
118
|
+
import { Optional } from 'semantic-typescript';
|
|
119
|
+
|
|
120
|
+
// Создать экземпляр Optional
|
|
121
|
+
const optionalValue = Optional.ofNullable<string>(Math.random() > 0.5 ? "hello" : null);
|
|
122
|
+
|
|
123
|
+
// Цепочка операций
|
|
124
|
+
const result = optionalValue
|
|
125
|
+
.filter(val => val.length > 3) // Отфильтровать значения длиннее 3
|
|
126
|
+
.map(val => val.toUpperCase()) // Преобразовать в верхний регистр
|
|
127
|
+
.getOrDefault("default"); // Получить значение или значение по умолчанию
|
|
128
|
+
|
|
129
|
+
console.log(result); // "HELLO" или "default"
|
|
130
|
+
|
|
131
|
+
// Безопасные операции
|
|
132
|
+
optionalValue.ifPresent(val => {
|
|
133
|
+
console.log(`Значение существует: ${val}`);
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
// Проверить статус
|
|
137
|
+
if (optionalValue.isPresent()) {
|
|
138
|
+
console.log("Есть значение");
|
|
139
|
+
} else if (optionalValue.isEmpty()) {
|
|
140
|
+
console.log("Пустое");
|
|
141
|
+
}
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
### Semantic<E> - Ленивый поток данных
|
|
145
|
+
|
|
146
|
+
Semantic - это основной класс потоковой обработки, предоставляющий богатый набор операторов потоков.
|
|
147
|
+
|
|
148
|
+
#### Операции преобразования потоков
|
|
149
|
+
|
|
150
|
+
| Метод | Тип возврата | Описание | Влияние на производительность |
|
|
151
|
+
|------|----------|------|----------|
|
|
152
|
+
| `concat(other: Semantic<E>)` | `Semantic<E>` | Объединить два потока | O(n+m) |
|
|
153
|
+
| `distinct()` | `Semantic<E>` | Удалить дубликаты (используя Set) | O(n) |
|
|
154
|
+
| `distinct(comparator)` | `Semantic<E>` | Дедубликация с пользовательским компаратором | O(n²) |
|
|
155
|
+
| `dropWhile(predicate)` | `Semantic<E>` | Отбросить начальные элементы, удовлетворяющие условию | O(n) |
|
|
156
|
+
| `filter(predicate)` | `Semantic<E>` | Отфильтровать элементы | O(n) |
|
|
157
|
+
| `flat(mapper)` | `Semantic<E>` | Развернуть вложенные потоки | O(n×m) |
|
|
158
|
+
| `flatMap(mapper)` | `Semantic<R>` | Отобразить и развернуть | O(n×m) |
|
|
159
|
+
| `limit(n)` | `Semantic<E>` | Ограничить количество элементов | O(n) |
|
|
160
|
+
| `map(mapper)` | `Semantic<R>` | Отобразить и преобразовать элементы | O(n) |
|
|
161
|
+
| `peek(consumer)` | `Semantic<E>` | Просмотреть элементы без модификации | O(n) |
|
|
162
|
+
| `redirect(redirector)` | `Semantic<E>` | Перенаправить индексы | O(n) |
|
|
163
|
+
| `reverse()` | `Semantic<E>` | Обратить порядок потока | O(n) |
|
|
164
|
+
| `shuffle()` | `Semantic<E>` | Случайно перемешать порядок | O(n) |
|
|
165
|
+
| `shuffle(mapper)` | `Semantic<E>` | Пользовательская логика перемешивания | O(n) |
|
|
166
|
+
| `skip(n)` | `Semantic<E>` | Пропустить первые n элементов | O(n) |
|
|
167
|
+
| `sub(start, end)` | `Semantic<E>` | Получить подпоток | O(n) |
|
|
168
|
+
| `takeWhile(predicate)` | `Semantic<E>` | Получить начальные элементы, удовлетворяющие условию | O(n) |
|
|
169
|
+
| `translate(offset)` | `Semantic<E>` | Транслировать индексы | O(n) |
|
|
170
|
+
| `translate(translator)` | `Semantic<E>` | Пользовательское преобразование индексов | O(n) |
|
|
171
|
+
|
|
172
|
+
**Дополнение с примером кода:**
|
|
173
|
+
```typescript
|
|
174
|
+
import { from } from 'semantic-typescript';
|
|
175
|
+
|
|
176
|
+
const stream = from([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
|
|
177
|
+
|
|
178
|
+
// Примеры операций преобразования потока
|
|
179
|
+
const processedStream = stream
|
|
180
|
+
.filter(x => x % 2 === 0) // Отфильтровать четные числа
|
|
181
|
+
.map(x => x * 2) // Умножить каждый элемент на 2
|
|
182
|
+
.distinct() // Удалить дубликаты
|
|
183
|
+
.limit(3) // Ограничить первыми 3 элементами
|
|
184
|
+
.peek((val, index) => console.log(`Элемент ${val} по индексу ${index}`)); // Просмотреть элементы
|
|
185
|
+
|
|
186
|
+
// Примечание: Поток еще не выполнен, требуется преобразование в Collectable для терминальных операций
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
#### Терминальные операции потоков
|
|
190
|
+
|
|
191
|
+
| Метод | Тип возврата | Описание | Характеристики производительности |
|
|
192
|
+
|------|----------|------|----------|
|
|
193
|
+
| `toOrdered()` | `OrderedCollectable<E>` | Преобразовать в упорядоченную коллекцию | Операция сортировки, низкая производительность |
|
|
194
|
+
| `toUnordered()` | `UnorderedCollectable<E>` | Преобразовать в неупорядоченную коллекцию | Самый быстрый, без сортировки |
|
|
195
|
+
| `toWindow()` | `WindowCollectable<E>` | Преобразовать в оконную коллекцию | Операция сортировки, низкая производительность |
|
|
196
|
+
| `toNumericStatistics()` | `Statistics<E, number>` | Численный статистический анализ | Операция сортировки, низкая производительность |
|
|
197
|
+
| `toBigintStatistics()` | `Statistics<E, bigint>` | Статистический анализ для больших целых чисел | Операция сортировки, низкая производительность |
|
|
198
|
+
| `sorted()` | `OrderedCollectable<E>` | Естественная сортировка | Переопределяет результаты перенаправления |
|
|
199
|
+
| `sorted(comparator)` | `OrderedCollectable<E>` | Пользовательская сортировка | Переопределяет результаты перенаправления |
|
|
200
|
+
|
|
201
|
+
**Дополнение с примером кода:**
|
|
202
|
+
```typescript
|
|
203
|
+
import { from } from 'semantic-typescript';
|
|
204
|
+
|
|
205
|
+
const semanticStream = from([5, 2, 8, 1, 9, 3, 7, 4, 6]);
|
|
206
|
+
|
|
207
|
+
// Преобразовать в упорядоченную коллекцию (низкая производительность)
|
|
208
|
+
const ordered = semanticStream.toOrdered();
|
|
209
|
+
|
|
210
|
+
// Преобразовать в неупорядоченную коллекцию (самый быстрый)
|
|
211
|
+
const unordered = semanticStream.toUnordered();
|
|
212
|
+
|
|
213
|
+
// Естественная сортировка
|
|
214
|
+
const sortedNatural = semanticStream.sorted();
|
|
215
|
+
|
|
216
|
+
// Пользовательская сортировка
|
|
217
|
+
const sortedCustom = semanticStream.sorted((a, b) => b - a); // Сортировка по убыванию
|
|
218
|
+
|
|
219
|
+
// Преобразовать в статистический объект
|
|
220
|
+
const stats = semanticStream.toNumericStatistics();
|
|
221
|
+
|
|
222
|
+
// Примечание: Необходимо вызывать указанные выше методы через экземпляр Semantic, чтобы получить Collectable, перед использованием терминальных методов
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
### Collector<E, A, R> - Сборщик данных
|
|
226
|
+
|
|
227
|
+
Коллекторы используются для агрегации потоковых данных в определенные структуры.
|
|
228
|
+
|
|
229
|
+
| Метод | Описание | Сценарий использования |
|
|
230
|
+
|------|------|----------|
|
|
231
|
+
| `collect(generator)` | Выполнить сбор данных | Терминальная операция потока |
|
|
232
|
+
| `static full(identity, accumulator, finisher)` | Создать полный коллектор | Требует полной обработки |
|
|
233
|
+
| `static shortable(identity, interruptor, accumulator, finisher)` | Создать прерываемый коллектор | Может завершиться досрочно |
|
|
234
|
+
|
|
235
|
+
**Дополнение с примером кода:**
|
|
236
|
+
```typescript
|
|
237
|
+
import { Collector } from 'semantic-typescript';
|
|
238
|
+
|
|
239
|
+
// Создать пользовательский коллектор
|
|
240
|
+
const sumCollector = Collector.full(
|
|
241
|
+
() => 0, // Начальное значение
|
|
242
|
+
(acc, value) => acc + value, // Аккумулятор
|
|
243
|
+
result => result // Функция завершения
|
|
244
|
+
);
|
|
245
|
+
|
|
246
|
+
// Использовать коллектор (требуется преобразование из Semantic в Collectable сначала)
|
|
247
|
+
const numbers = from([1, 2, 3, 4, 5]);
|
|
248
|
+
const sum = numbers.toUnordered().collect(sumCollector); // 15
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
### Collectable<E> - Абстрактный класс собираемых данных
|
|
252
|
+
|
|
253
|
+
Предоставляет богатые методы агрегации и преобразования данных. **Примечание: Сначала необходимо получить экземпляр Collectable, вызвав sorted(), toOrdered() и т.д. через экземпляр Semantic, перед использованием следующих методов.**
|
|
254
|
+
|
|
255
|
+
#### Операции запроса данных
|
|
256
|
+
|
|
257
|
+
| Метод | Тип возврата | Описание | Пример |
|
|
258
|
+
|------|----------|------|------|
|
|
259
|
+
| `anyMatch(predicate)` | `boolean` | Соответствует ли любой элемент | `anyMatch(x => x > 0)` |
|
|
260
|
+
| `allMatch(predicate)` | `boolean` | Соответствуют ли все элементы | `allMatch(x => x > 0)` |
|
|
261
|
+
| `count()` | `bigint` | Статистика количества элементов | `count()` → `5n` |
|
|
262
|
+
| `isEmpty()` | `boolean` | Является ли поток пустым | `isEmpty()` |
|
|
263
|
+
| `findAny()` | `Optional<E>` | Найти любой элемент | `findAny()` |
|
|
264
|
+
| `findFirst()` | `Optional<E>` | Найти первый элемент | `findFirst()` |
|
|
265
|
+
| `findLast()` | `Optional<E>` | Найти последний элемент | `findLast()` |
|
|
266
|
+
|
|
267
|
+
**Дополнение с примером кода:**
|
|
268
|
+
```typescript
|
|
269
|
+
import { from } from 'semantic-typescript';
|
|
270
|
+
|
|
271
|
+
const numbers = from([1, 2, 3, 4, 5]);
|
|
272
|
+
|
|
273
|
+
// Необходимо преобразовать в Collectable перед использованием терминальных методов
|
|
274
|
+
const collectable = numbers.toUnordered();
|
|
275
|
+
|
|
276
|
+
// Операции запроса данных
|
|
277
|
+
const hasEven = collectable.anyMatch(x => x % 2 === 0); // true
|
|
278
|
+
const allPositive = collectable.allMatch(x => x > 0); // true
|
|
279
|
+
const count = collectable.count(); // 5n
|
|
280
|
+
const isEmpty = collectable.isEmpty(); // false
|
|
281
|
+
const firstElement = collectable.findFirst(); // Optional.of(1)
|
|
282
|
+
const anyElement = collectable.findAny(); // Любой элемент
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
#### Операции агрегации данных
|
|
286
|
+
|
|
287
|
+
| Метод | Тип возврата | Описание | Сложность |
|
|
288
|
+
|------|----------|------|--------|
|
|
289
|
+
| `group(classifier)` | `Map<K, E[]>` | Группировать по классификатору | O(n) |
|
|
290
|
+
| `groupBy(keyExtractor, valueExtractor)` | `Map<K, V[]>` | Группировать по экстракторам ключ-значение | O(n) |
|
|
291
|
+
| `join()` | `string` | Объединить в строку | O(n) |
|
|
292
|
+
| `join(delimiter)` | `string` | Объединить с разделителем | O(n) |
|
|
293
|
+
| `partition(count)` | `E[][]` | Разделить по количеству | O(n) |
|
|
294
|
+
| `partitionBy(classifier)` | `E[][]` | Разделить по классификатору | O(n) |
|
|
295
|
+
| `reduce(accumulator)` | `Optional<E>` | Операция редукции | O(n) |
|
|
296
|
+
| `reduce(identity, accumulator)` | `E` | Редукция с начальным значением | O(n) |
|
|
297
|
+
| `toArray()` | `E[]` | Преобразовать в массив | O(n) |
|
|
298
|
+
| `toMap(keyExtractor, valueExtractor)` | `Map<K, V>` | Преобразовать в Map | O(n) |
|
|
299
|
+
| `toSet()` | `Set<E>` | Преобразовать в Set | O(n) |
|
|
300
|
+
|
|
301
|
+
**Дополнение с примером кода:**
|
|
302
|
+
```typescript
|
|
303
|
+
import { from } from 'semantic-typescript';
|
|
304
|
+
|
|
305
|
+
const people = from([
|
|
306
|
+
{ name: "Alice", age: 25, city: "New York" },
|
|
307
|
+
{ name: "Bob", age: 30, city: "London" },
|
|
308
|
+
{ name: "Charlie", age: 25, city: "New York" }
|
|
309
|
+
]);
|
|
310
|
+
|
|
311
|
+
// Необходимо преобразовать в Collectable перед использованием операций агрегации
|
|
312
|
+
const collectable = people.toUnordered();
|
|
313
|
+
|
|
314
|
+
// Операции группировки
|
|
315
|
+
const byCity = collectable.group(person => person.city);
|
|
316
|
+
// Map { "New York" => [{name: "Alice", ...}, {name: "Charlie", ...}], "London" => [{name: "Bob", ...}] }
|
|
317
|
+
|
|
318
|
+
const byAge = collectable.groupBy(
|
|
319
|
+
person => person.age,
|
|
320
|
+
person => person.name
|
|
321
|
+
);
|
|
322
|
+
// Map { 25 => ["Alice", "Charlie"], 30 => ["Bob"] }
|
|
323
|
+
|
|
324
|
+
// Преобразовать в коллекции
|
|
325
|
+
const array = collectable.toArray(); // Исходный массив
|
|
326
|
+
const set = collectable.toSet(); // Коллекция Set
|
|
327
|
+
const map = collectable.toMap(
|
|
328
|
+
person => person.name,
|
|
329
|
+
person => person.age
|
|
330
|
+
); // Map { "Alice" => 25, "Bob" => 30, "Charlie" => 25 }
|
|
331
|
+
|
|
332
|
+
// Операции редукции
|
|
333
|
+
const totalAge = collectable.reduce(0, (acc, person) => acc + person.age); // 80
|
|
334
|
+
const oldest = collectable.reduce((a, b) => a.age > b.age ? a : b); // Optional.of({name: "Bob", age: 30, ...})
|
|
335
|
+
```
|
|
336
|
+
|
|
337
|
+
### Конкретные реализации коллекторов
|
|
338
|
+
|
|
339
|
+
#### UnorderedCollectable<E>
|
|
340
|
+
- **Характеристики**: Самый быстрый коллектор, без сортировки
|
|
341
|
+
- **Сценарии использования**: Порядок не важен, желательна максимальная производительность
|
|
342
|
+
- **Методы**: Наследует все методы Collectable
|
|
343
|
+
|
|
344
|
+
#### OrderedCollectable<E>
|
|
345
|
+
- **Характеристики**: Гарантирует порядок элементов, низкая производительность
|
|
346
|
+
- **Сценарии использования**: Требуются отсортированные результаты
|
|
347
|
+
- **Специальные методы**: Наследует все методы, сохраняет внутреннее состояние сортировки
|
|
348
|
+
|
|
349
|
+
#### WindowCollectable<E>
|
|
350
|
+
- **Характеристики**: Поддерживает операции скользящего окна
|
|
351
|
+
- **Сценарии использования**: Анализ временных рядов
|
|
352
|
+
- **Специальные методы**:
|
|
353
|
+
- `slide(size, step)` - Скользящее окно
|
|
354
|
+
- `tumble(size)` - Тумблинг-окно
|
|
355
|
+
|
|
356
|
+
**Дополнение с примером кода:**
|
|
357
|
+
```typescript
|
|
358
|
+
import { from } from 'semantic-typescript';
|
|
359
|
+
|
|
360
|
+
const data = from([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
|
|
361
|
+
|
|
362
|
+
// Неупорядоченный коллектор (самый быстрый)
|
|
363
|
+
const unordered = data.toUnordered();
|
|
364
|
+
const unorderedArray = unordered.toArray(); // Может сохранять исходный порядок [1, 2, 3, ...]
|
|
365
|
+
|
|
366
|
+
// Упорядоченный коллектор
|
|
367
|
+
const ordered = data.toOrdered();
|
|
368
|
+
const orderedArray = ordered.toArray(); // Гарантированно отсортирован [1, 2, 3, ...]
|
|
369
|
+
|
|
370
|
+
// Оконный коллектор
|
|
371
|
+
const windowed = data.toWindow();
|
|
372
|
+
const slidingWindows = windowed.slide(3n, 2n); // Размер окна 3, шаг 2
|
|
373
|
+
// Окно 1: [1, 2, 3], Окно 2: [3, 4, 5], Окно 3: [5, 6, 7], ...
|
|
374
|
+
|
|
375
|
+
const tumblingWindows = windowed.tumble(4n); // Размер тумблинг-окна 4
|
|
376
|
+
// Окно 1: [1, 2, 3, 4], Окно 2: [5, 6, 7, 8], ...
|
|
377
|
+
```
|
|
378
|
+
|
|
379
|
+
### Statistics<E, D> - Статистический анализ
|
|
380
|
+
|
|
381
|
+
Базовый класс статистического анализа, предоставляющий богатые методы статистических вычислений. **Примечание: Сначала необходимо получить экземпляр Statistics, вызвав toNumericStatistics() или toBigIntStatistics() через экземпляр Semantic, перед использованием следующих методов.**
|
|
382
|
+
|
|
383
|
+
#### Операции статистических вычислений
|
|
384
|
+
|
|
385
|
+
| Метод | Тип возврата | Описание | Сложность алгоритма |
|
|
386
|
+
|------|----------|------|------------|
|
|
387
|
+
| `maximum()` | `Optional<E>` | Максимальное значение | O(n) |
|
|
388
|
+
| `minimum()` | `Optional<E>` | Минимальное значение | O(n) |
|
|
389
|
+
| `range()` | `D` | Размах (макс-мин) | O(n) |
|
|
390
|
+
| `variance()` | `D` | Дисперсия | O(n) |
|
|
391
|
+
| `standardDeviation()` | `D` | Стандартное отклонение | O(n) |
|
|
392
|
+
| `mean()` | `D` | Среднее значение | O(n) |
|
|
393
|
+
| `median()` | `D` | Медиана | O(n log n) |
|
|
394
|
+
| `mode()` | `D` | Мода | O(n) |
|
|
395
|
+
| `frequency()` | `Map<D, bigint>` | Распределение частот | O(n) |
|
|
396
|
+
| `summate()` | `D` | Суммирование | O(n) |
|
|
397
|
+
| `quantile(quantile)` | `D` | Квантиль | O(n log n) |
|
|
398
|
+
| `interquartileRange()` | `D` | Интерквартильный размах | O(n log n) |
|
|
399
|
+
| `skewness()` | `D` | Асимметрия | O(n) |
|
|
400
|
+
| `kurtosis()` | `D` | Эксцесс | O(n) |
|
|
401
|
+
|
|
402
|
+
**Дополнение с примером кода:**
|
|
403
|
+
```typescript
|
|
404
|
+
import { from } from 'semantic-typescript';
|
|
405
|
+
|
|
406
|
+
const numbers = from([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
|
|
407
|
+
|
|
408
|
+
// Необходимо преобразовать в статистический объект перед использованием статистических методов
|
|
409
|
+
const stats = numbers.toNumericStatistics();
|
|
410
|
+
|
|
411
|
+
// Базовая статистика
|
|
412
|
+
const count = stats.count(); // 10n
|
|
413
|
+
const max = stats.maximum(); // Optional.of(10)
|
|
414
|
+
const min = stats.minimum(); // Optional.of(1)
|
|
415
|
+
const range = stats.range(); // 9
|
|
416
|
+
const mean = stats.mean(); // 5.5
|
|
417
|
+
const median = stats.median(); // 5.5
|
|
418
|
+
const sum = stats.summate(); // 55
|
|
419
|
+
|
|
420
|
+
// Продвинутая статистика
|
|
421
|
+
const variance = stats.variance(); // 8.25
|
|
422
|
+
const stdDev = stats.standardDeviation(); // 2.872
|
|
423
|
+
const mode = stats.mode(); // Любое значение (так как все встречаются по одному разу)
|
|
424
|
+
const q1 = stats.quantile(0.25); // 3.25
|
|
425
|
+
const q3 = stats.quantile(0.75); // 7.75
|
|
426
|
+
const iqr = stats.interquartileRange(); // 4.5
|
|
427
|
+
|
|
428
|
+
// Распределение частот
|
|
429
|
+
const freq = stats.frequency(); // Map {1 => 1n, 2 => 1n, ...}
|
|
430
|
+
```
|
|
431
|
+
|
|
432
|
+
#### Конкретные классы статистических реализаций
|
|
433
|
+
|
|
434
|
+
**NumericStatistics<E>**
|
|
435
|
+
- Обрабатывает статистический анализ числового типа
|
|
436
|
+
- Все статистические вычисления возвращают числовой тип
|
|
437
|
+
|
|
438
|
+
**BigIntStatistics<E>**
|
|
439
|
+
- Обрабатывает статистический анализ типа bigint
|
|
440
|
+
- Все статистические вычисления возвращают тип bigint
|
|
441
|
+
|
|
442
|
+
**Дополнение с примером кода:**
|
|
443
|
+
```typescript
|
|
444
|
+
import { from } from 'semantic-typescript';
|
|
445
|
+
|
|
446
|
+
// Числовая статистика
|
|
447
|
+
const numberData = from([10, 20, 30, 40, 50]);
|
|
448
|
+
const numericStats = numberData.toNumericStatistics();
|
|
449
|
+
|
|
450
|
+
console.log(numericStats.mean()); // 30
|
|
451
|
+
console.log(numericStats.summate()); // 150
|
|
452
|
+
|
|
453
|
+
// Статистика больших целых чисел
|
|
454
|
+
const bigintData = from([100n, 200n, 300n, 400n, 500n]);
|
|
455
|
+
const bigintStats = bigintData.toBigIntStatistics();
|
|
456
|
+
|
|
457
|
+
console.log(bigintStats.mean()); // 300n
|
|
458
|
+
console.log(bigintStats.summate()); // 1500n
|
|
459
|
+
|
|
460
|
+
// Статистика с использованием функций-мапперов
|
|
461
|
+
const objectData = from([
|
|
462
|
+
{ value: 15 },
|
|
463
|
+
{ value: 25 },
|
|
464
|
+
{ value: 35 },
|
|
465
|
+
{ value: 45 }
|
|
466
|
+
]);
|
|
467
|
+
|
|
468
|
+
const objectStats = objectData.toNumericStatistics();
|
|
469
|
+
const meanWithMapper = objectStats.mean(obj => obj.value); // 30
|
|
470
|
+
const sumWithMapper = objectStats.summate(obj => obj.value); // 120
|
|
471
|
+
```
|
|
472
|
+
|
|
473
|
+
## Полный пример использования
|
|
474
|
+
|
|
475
|
+
```typescript
|
|
476
|
+
import { from, validate, invalidate } from 'semantic-typescript';
|
|
477
|
+
|
|
478
|
+
// 1. Создать поток данных
|
|
479
|
+
const rawData = [5, 2, 8, 1, null, 9, 3, undefined, 7, 4, 6];
|
|
480
|
+
const semanticStream = from(rawData);
|
|
481
|
+
|
|
482
|
+
// 2. Конвейер обработки потока
|
|
483
|
+
const processedStream = semanticStream
|
|
484
|
+
.filter(val => validate(val)) // Отфильтровать null и undefined
|
|
485
|
+
.map(val => val! * 2) // Умножить каждое значение на 2 (используется !, так как validate гарантирует не пустое)
|
|
486
|
+
.distinct(); // Удалить дубликаты
|
|
487
|
+
|
|
488
|
+
// 3. Преобразовать в Collectable и использовать терминальные операции
|
|
489
|
+
const collectable = processedStream.toUnordered();
|
|
490
|
+
|
|
491
|
+
// 4. Проверка данных и использование
|
|
492
|
+
if (!collectable.isEmpty()) {
|
|
493
|
+
const results = collectable
|
|
494
|
+
.filter(x => x > 5) // Снова отфильтровать
|
|
495
|
+
.toArray(); // Преобразовать в массив
|
|
496
|
+
|
|
497
|
+
console.log("Результаты обработки:", results); // [16, 18, 14, 8, 12]
|
|
498
|
+
|
|
499
|
+
// Статистическая информация
|
|
500
|
+
const stats = processedStream.toNumericStatistics();
|
|
501
|
+
console.log("Среднее значение:", stats.mean()); // 11.2
|
|
502
|
+
console.log("Общая сумма:", stats.summate()); // 56
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
// 5. Обработать потенциально невалидные данные
|
|
506
|
+
const potentiallyInvalidData: Array<number | null> = [1, null, 3, 4, null];
|
|
507
|
+
const validData = potentiallyInvalidData.filter(validate);
|
|
508
|
+
const invalidData = potentiallyInvalidData.filter(invalidate);
|
|
509
|
+
|
|
510
|
+
console.log("Валидные данные:", validData); // [1, 3, 4]
|
|
511
|
+
console.log("Невалидные данные:", invalidData); // [null, null]
|
|
512
|
+
```
|
|
513
|
+
|
|
514
|
+
## Важные правила использования - итог
|
|
515
|
+
|
|
516
|
+
1. **Создать поток**: Используйте фабричные методы `from()`, `range()`, `fill()` и т.д. для создания экземпляров Semantic
|
|
517
|
+
2. **Преобразование потока**: Вызывайте методы `map()`, `filter()`, `distinct()` и т.д. на экземплярах Semantic
|
|
518
|
+
3. **Преобразовать в Collectable**: Необходимо вызвать один из следующих методов через экземпляр Semantic:
|
|
519
|
+
- `toOrdered()` - Упорядоченный коллектор
|
|
520
|
+
- `toUnordered()` - Неупорядоченный коллектор (самый быстрый)
|
|
521
|
+
- `toWindow()` - Оконный коллектор
|
|
522
|
+
- `toNumericStatistics()` - Числовая статистика
|
|
523
|
+
- `toBigIntStatistics()` - Статистика больших целых чисел
|
|
524
|
+
- `sorted()` - Естественная сортировка
|
|
525
|
+
- `sorted(comparator)` - Пользовательская сортировка
|
|
526
|
+
4. **Терминальные операции**: Вызывайте терминальные методы `toArray()`, `count()`, `summate()` и т.д. на экземплярах Collectable
|
|
527
|
+
5. **Проверка данных**: Используйте `validate()` для гарантии, что данные не null/undefined, используйте `invalidate()` для проверки невалидных данных
|
|
528
|
+
|
|
529
|
+
Этот дизайн обеспечивает типобезопасность и оптимизацию производительности, предоставляя при этом богатый функционал потоковой обработки.
|