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/readme.es.md CHANGED
@@ -1,335 +1,529 @@
1
- # 📘 semantic-typescript
1
+ # Framework de Procesamiento de Flujos Semantic-TypeScript
2
2
 
3
- Una poderosa biblioteca de utilidades para **procesamiento semántico de datos** en TypeScript, completamente **segura y tipada**.
4
- Proporciona construcciones funcionales compuestas para trabajar con colecciones, flujos y secuencias — con soporte para ordenar, filtrar, agrupar, realizar análisis estadísticos y más.
3
+ ## Introducción
5
4
 
6
- Ya sea que estés procesando **datos ordenados o no ordenados**, realizando **análisis estadísticos**, o simplemente **encadenando operaciones de forma fluida**, esta biblioteca está diseñada para cubrir todas tus necesidades.
5
+ Semantic-TypeScript es una librería moderna de procesamiento de flujos inspirada en GeneratorFunction de JavaScript, Java Stream e Índices de MySQL. La filosofía de diseño central se basa en construir pipelines eficientes de procesamiento de datos mediante indexación de datos, proporcionando una experiencia de operación de streaming en estilo funcional y type-safe para el desarrollo frontend.
7
6
 
8
- ---
7
+ A diferencia del procesamiento sincrónico tradicional, Semantic emplea un modelo de procesamiento asíncrono. Al crear flujos de datos, el momento de recepción de datos terminales depende completamente de cuándo la corriente superior llama a las funciones callback `accept` e `interrupt`. Este diseño permite que la librería maneje elegantemente flujos de datos en tiempo real, grandes conjuntos de datos y fuentes de datos asíncronas.
9
8
 
10
- ## 🧩 Características
9
+ ## Características Principales
11
10
 
12
- - **Genéricos tipados de forma segura** en toda la biblioteca
13
- - ✅ Estilo **funcional** (map, filter, reduce, etc.)
14
- - **Flujos de datos semánticos** (`Semantic<E>`) para evaluación diferida (lazy)
15
- - **Coleccionadores (Collectors)** para transformar flujos en estructuras concretas
16
- - **Collectables ordenados y no ordenados** `toUnordered()` es **el más rápido (sin ordenar)**
17
- - **Soporte para ordenar** mediante `sorted()`, `toOrdered()`, y comparadores personalizados
18
- - **Análisis estadístico** (`Statistics`, `NumericStatistics`, `BigIntStatistics`)
19
- - **Optional<T>** monada para manejar valores nulos de forma segura
20
- - ✅ Diseño basado en **iteradores y generadores** — ideal para grandes volúmenes o datos asíncronos
11
+ | Característica | Descripción | Ventaja |
12
+ |------|------|------|
13
+ | **Genéricos Type-Safe** | Soporte completo de tipos TypeScript | Detección de errores en tiempo de compilación, mejor experiencia de desarrollo |
14
+ | **Programación Funcional** | Estructuras de datos inmutables y funciones puras | Código más predecible, más fácil de probar y mantener |
15
+ | **Evaluación Perezosa** | Cálculo bajo demanda, optimización de rendimiento | Alta eficiencia de memoria al procesar grandes conjuntos de datos |
16
+ | **Procesamiento Asíncrono de Flujos** | Flujos de datos asíncronos basados en generadores | Adecuado para datos en tiempo real y escenarios orientados a eventos |
17
+ | **Colectores Multi-Paradigma** | Estrategias de recolección ordenadas, desordenadas y estadísticas | Selección de estrategia óptima basada en diferentes escenarios |
18
+ | **Análisis Estadístico** | Funciones completas integradas de cálculo estadístico | Generación integrada de análisis de datos e informes |
21
19
 
22
- ---
20
+ ## Consideraciones de Rendimiento
23
21
 
24
- ## 📦 Instalación
22
+ **Nota Importante**: Los siguientes métodos sacrifican rendimiento para recolectar y ordenar datos, resultando en colecciones de datos ordenadas:
23
+ - `toOrdered()`
24
+ - `toWindow()`
25
+ - `toNumericStatistics()`
26
+ - `toBigIntStatistics()`
27
+ - `sorted()`
28
+ - `sorted(comparator)`
25
29
 
26
- ```bash
27
- npm install semantic-typescript
28
- ```
29
-
30
- ---
31
-
32
- ## 🧠 Conceptos clave
33
-
34
- ### 1. `Optional<T>` — Manejo seguro de valores nulos
35
-
36
- Un contenedor monádico para valores que pueden ser `null` o `undefined`.
30
+ Especialmente importante notar: `sorted()` y `sorted(comparator)` anularán los resultados de los siguientes métodos:
31
+ - `redirect(redirector)`
32
+ - `translate(translator)`
33
+ - `shuffle(mapper)`
37
34
 
38
- #### Métodos:
35
+ ## Métodos de Fábrica
39
36
 
40
- | Método | Descripción | Ejemplo |
41
- |--------|-------------|---------|
42
- | `of(value)` | Envolver un valor (puede ser nulo) | `Optional.of(null)` |
43
- | `ofNullable(v)` | Envolver, permite valores nulos | `Optional.ofNullable(someVar)` |
44
- | `ofNonNull(v)` | Envolver, lanza excepción si es nulo/undefined | `Optional.ofNonNull(5)` |
45
- | `get()` | Obtener el valor (o lanzar excepción si está vacío) | `opt.get()` |
46
- | `getOrDefault(d)` | Obtener el valor o un valor por defecto | `opt.getOrDefault(0)` |
47
- | `ifPresent(fn)` | Ejecutar un efecto secundario si hay valor | `opt.ifPresent(x => console.log(x))` |
48
- | `map(fn)` | Transformar el valor si existe | `opt.map(x => x + 1)` |
49
- | `filter(fn)` | Conservar el valor solo si cumple el predicado | `opt.filter(x => x > 0)` |
50
- | `isEmpty()` | Verificar si está vacío | `opt.isEmpty()` |
51
- | `isPresent()` | Verificar si tiene un valor | `opt.isPresent()` |
37
+ ### Fábricas de Creación de Flujos
52
38
 
53
- #### Ejemplo:
39
+ | Método | Firma | Descripción | Ejemplo |
40
+ |------|------|------|------|
41
+ | `blob` | `(blob: Blob, chunk?: bigint) => Semantic<Uint8Array>` | Convertir Blob a flujo de bytes | `blob(fileBlob, 1024n)` |
42
+ | `empty` | `<E>() => Semantic<E>` | Crear flujo vacío | `empty<number>()` |
43
+ | `fill` | `<E>(element: E, count: bigint) => Semantic<E>` | Llenar con número especificado de elementos | `fill("hello", 5n)` |
44
+ | `from` | `<E>(iterable: Iterable<E>) => Semantic<E>` | Crear flujo desde objeto iterable | `from([1, 2, 3])` |
45
+ | `range` | `<N extends number\|bigint>(start: N, end: N, step?: N) => Semantic<N>` | Crear flujo de rango numérico | `range(1, 10, 2)` |
46
+ | `iterate` | `<E>(generator: Generator<E>) => Semantic<E>` | Crear flujo desde función generadora | `iterate(myGenerator)` |
47
+ | `websocket` | `(websocket: WebSocket) => Semantic<MessageEvent>` | Crear flujo de eventos desde WebSocket | `websocket(socket)` |
54
48
 
49
+ **Suplemento de Ejemplo de Código:**
55
50
  ```typescript
56
- import { Optional } from 'semantic-typescript';
51
+ import { from, range, fill, empty } from 'semantic-typescript';
57
52
 
58
- const value: number | null = Math.random() > 0.5 ? 10 : null;
53
+ // Crear flujo desde array
54
+ const numberStream = from([1, 2, 3, 4, 5]);
59
55
 
60
- const opt = Optional.ofNullable(value);
56
+ // Crear flujo de rango numérico
57
+ const rangeStream = range(1, 10, 2); // 1, 3, 5, 7, 9
61
58
 
62
- const result = opt
63
- .filter(v => v > 5)
64
- .map(v => v * 2)
65
- .getOrDefault(0);
59
+ // Llenar con elementos repetidos
60
+ const filledStream = fill("hello", 3n); // "hello", "hello", "hello"
66
61
 
67
- console.log(result); // 20 o 0
62
+ // Crear flujo vacío
63
+ const emptyStream = empty<number>();
68
64
  ```
69
65
 
70
- ---
66
+ ### Fábricas de Funciones de Utilidad
71
67
 
72
- ### 2. `Semantic<E>` Flujo de datos diferido
68
+ | Método | Firma | Descripción | Ejemplo |
69
+ |------|------|------|------|
70
+ | `validate` | `<T>(t: MaybeInvalid<T>) => t is T` | Validar si el valor es válido | `validate(null)` → `false` |
71
+ | `invalidate` | `<T>(t: MaybeInvalid<T>) => t is null\|undefined` | Validar si el valor es inválido | `invalidate(0)` → `false` |
72
+ | `useCompare` | `<T>(t1: T, t2: T) => number` | Función de comparación genérica | `useCompare("a", "b")` → `-1` |
73
+ | `useRandom` | `<T = number\|bigint>(index: T) => T` | Generador de números pseudoaleatorios | `useRandom(5)` → número aleatorio |
73
74
 
74
- Un **flujo secuencial diferido y compuesto**. Similar a Java Streams o Kotlin Sequences.
75
+ **Suplemento de Ejemplo de Código:**
76
+ ```typescript
77
+ import { validate, invalidate, useCompare, useRandom } from 'semantic-typescript';
75
78
 
76
- Puedes crear un `Semantic` usando funciones como `from()`, `range()`, `iterate()` o `fill()`.
79
+ // Validar validez de datos
80
+ const data: string | null = "hello";
81
+ if (validate(data)) {
82
+ console.log(data.toUpperCase()); // Llamada segura porque validate asegura que data no es null
83
+ }
77
84
 
78
- #### Creadores:
85
+ const nullData: string | null = null;
86
+ if (invalidate(nullData)) {
87
+ console.log("Datos inválidos"); // Se ejecutará porque invalidate detectó null
88
+ }
79
89
 
80
- | Función | Descripción | Ejemplo |
81
- |--------|-------------|---------|
82
- | `from(iterable)` | Crear desde un Array, Set, Iterable | `from([1, 2, 3])` |
83
- | `range(start, end, step?)` | Generar una secuencia de números | `range(0, 5)` → 0,1,2,3,4 |
84
- | `fill(element, count)` | Repetir un elemento N veces | `fill('a', 3n)` |
85
- | `iterate(gen)` | Usar una función generadora personalizada | `iterate(genFn)` |
90
+ // Comparar valores
91
+ const comparison = useCompare("apple", "banana"); // -1
86
92
 
87
- #### Operadores comunes:
93
+ // Generar número aleatorio
94
+ const randomNum = useRandom(42); // Número aleatorio basado en semilla 42
95
+ ```
88
96
 
89
- | Método | Descripción | Ejemplo |
90
- |--------|-------------|---------|
91
- | `map(fn)` | Transformar cada elemento | `.map(x => x * 2)` |
92
- | `filter(fn)` | Conservar elementos que cumplen el predicado | `.filter(x => x > 10)` |
93
- | `limit(n)` | Limitar a los primeros N elementos | `.limit(5)` |
94
- | `skip(n)` | Saltar los primeros N elementos | `.skip(2)` |
95
- | `distinct()` | Eliminar duplicados (usa Set por defecto) | `.distinct()` |
96
- | `sorted()` | Ordenar elementos (orden natural) | `.sorted()` |
97
- | `sorted(comparator)` | Ordenar con un comparador personalizado | `.sorted((a, b) => a - b)` |
98
- | `toOrdered()` | Ordenar y devolver un `OrderedCollectable` | `.toOrdered()` |
99
- | `toUnordered()` | **Sin ordenar** — el más rápido | `.toUnordered()` ✅ |
100
- | `collect(collector)` | Agregar usando un `Collector` | `.collect(Collector.full(...))` |
101
- | `toArray()` | Convertir a Array | `.toArray()` |
102
- | `toSet()` | Convertir a Set | `.toSet()` |
103
- | `toMap(keyFn, valFn)` | Convertir a Map | `.toMap(x => x.id, x => x)` |
97
+ ## Detalles de la Clase Principal
104
98
 
105
- ---
99
+ ### Optional<T> - Manejo Seguro de Valores Nulos
106
100
 
107
- ### 3. `toUnordered()` 🚀 El más rápido, sin ordenar
101
+ La clase Optional proporciona un enfoque funcional para manejar seguramente valores que pueden ser null o undefined.
108
102
 
109
- Si **no necesitas orden** y quieres el **máximo rendimiento**, utiliza:
103
+ | Método | Tipo de Retorno | Descripción | Complejidad Temporal |
104
+ |------|----------|------|------------|
105
+ | `filter(predicate: Predicate<T>)` | `Optional<T>` | Filtrar valores que satisfacen condición | O(1) |
106
+ | `get()` | `T` | Obtener valor, lanza error si está vacío | O(1) |
107
+ | `getOrDefault(defaultValue: T)` | `T` | Obtener valor o valor por defecto | O(1) |
108
+ | `ifPresent(action: Consumer<T>)` | `void` | Ejecutar acción si existe valor | O(1) |
109
+ | `isEmpty()` | `boolean` | Verificar si está vacío | O(1) |
110
+ | `isPresent()` | `boolean` | Verificar si existe valor | O(1) |
111
+ | `map<R>(mapper: Functional<T, R>)` | `Optional<R>` | Mapear y transformar valor | O(1) |
112
+ | `static of<T>(value: MaybeInvalid<T>)` | `Optional<T>` | Crear instancia Optional | O(1) |
113
+ | `static ofNullable<T>(value?)` | `Optional<T>` | Crear Optional nullable | O(1) |
114
+ | `static ofNonNull<T>(value: T)` | `Optional<T>` | Crear Optional no nulo | O(1) |
110
115
 
116
+ **Suplemento de Ejemplo de Código:**
111
117
  ```typescript
112
- const fastest = semanticStream.toUnordered();
113
- ```
118
+ import { Optional } from 'semantic-typescript';
114
119
 
115
- 🔥 **No se aplica ningún algoritmo de ordenamiento.**
116
- Ideal cuando el orden no importa y la velocidad es prioritaria.
120
+ // Crear instancia Optional
121
+ const optionalValue = Optional.ofNullable<string>(Math.random() > 0.5 ? "hello" : null);
117
122
 
118
- ---
123
+ // Operaciones en cadena
124
+ const result = optionalValue
125
+ .filter(val => val.length > 3) // Filtrar valores más largos que 3
126
+ .map(val => val.toUpperCase()) // Convertir a mayúsculas
127
+ .getOrDefault("default"); // Obtener valor o por defecto
119
128
 
120
- ### 4. `toOrdered()` y `sorted()` Resultados ordenados
129
+ console.log(result); // "HELLO" o "default"
121
130
 
122
- Si necesitas un **resultado ordenado**, puedes usar:
131
+ // Operaciones seguras
132
+ optionalValue.ifPresent(val => {
133
+ console.log(`Valor existe: ${val}`);
134
+ });
123
135
 
124
- ```typescript
125
- const ordered = semanticStream.sorted(); // Orden natural
126
- const customSorted = semanticStream.sorted((a, b) => a - b); // Comparador personalizado
127
- const orderedCollectable = semanticStream.toOrdered(); // También ordenado
136
+ // Verificar estado
137
+ if (optionalValue.isPresent()) {
138
+ console.log("Tiene valor");
139
+ } else if (optionalValue.isEmpty()) {
140
+ console.log("Está vacío");
141
+ }
128
142
  ```
129
143
 
130
- ⚠️ Estos métodos **ordenarán los elementos**, usando orden natural o el comparador dado.
131
-
132
- ---
133
-
134
- ### 5. `Collector<E, A, R>` — Agregación de datos
144
+ ### Semantic<E> - Flujo de Datos Perezoso
145
+
146
+ Semantic es la clase principal de procesamiento de flujos, que proporciona operadores ricos de flujos.
147
+
148
+ #### Operaciones de Transformación de Flujos
149
+
150
+ | Método | Tipo de Retorno | Descripción | Impacto en Rendimiento |
151
+ |------|----------|------|----------|
152
+ | `concat(other: Semantic<E>)` | `Semantic<E>` | Concatenar dos flujos | O(n+m) |
153
+ | `distinct()` | `Semantic<E>` | Eliminar duplicados (usando Set) | O(n) |
154
+ | `distinct(comparator)` | `Semantic<E>` | Eliminación de duplicados con comparador personalizado | O(n²) |
155
+ | `dropWhile(predicate)` | `Semantic<E>` | Descartar elementos iniciales que satisfacen condición | O(n) |
156
+ | `filter(predicate)` | `Semantic<E>` | Filtrar elementos | O(n) |
157
+ | `flat(mapper)` | `Semantic<E>` | Aplanar flujos anidados | O(n×m) |
158
+ | `flatMap(mapper)` | `Semantic<R>` | Mapear y aplanar | O(n×m) |
159
+ | `limit(n)` | `Semantic<E>` | Limitar número de elementos | O(n) |
160
+ | `map(mapper)` | `Semantic<R>` | Mapear y transformar elementos | O(n) |
161
+ | `peek(consumer)` | `Semantic<E>` | Ver elementos sin modificación | O(n) |
162
+ | `redirect(redirector)` | `Semantic<E>` | Redirigir índices | O(n) |
163
+ | `reverse()` | `Semantic<E>` | Invertir orden del flujo | O(n) |
164
+ | `shuffle()` | `Semantic<E>` | Barajar orden aleatoriamente | O(n) |
165
+ | `shuffle(mapper)` | `Semantic<E>` | Lógica de barajado personalizada | O(n) |
166
+ | `skip(n)` | `Semantic<E>` | Saltar primeros n elementos | O(n) |
167
+ | `sub(start, end)` | `Semantic<E>` | Obtener subflujo | O(n) |
168
+ | `takeWhile(predicate)` | `Semantic<E>` | Obtener elementos iniciales que satisfacen condición | O(n) |
169
+ | `translate(offset)` | `Semantic<E>` | Traducir índices | O(n) |
170
+ | `translate(translator)` | `Semantic<E>` | Transformación de índices personalizada | O(n) |
171
+
172
+ **Suplemento de Ejemplo de Código:**
173
+ ```typescript
174
+ import { from } from 'semantic-typescript';
135
175
 
136
- Los **colectores** te permiten **reducir un flujo a una estructura única o compleja**.
176
+ const stream = from([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
137
177
 
138
- Existen fábricas estáticas como:
178
+ // Ejemplos de operaciones de transformación de flujos
179
+ const processedStream = stream
180
+ .filter(x => x % 2 === 0) // Filtrar números pares
181
+ .map(x => x * 2) // Multiplicar cada elemento por 2
182
+ .distinct() // Eliminar duplicados
183
+ .limit(3) // Limitar a primeros 3 elementos
184
+ .peek((val, index) => console.log(`Elemento ${val} en índice ${index}`)); // Ver elementos
139
185
 
140
- ```typescript
141
- Collector.full(identity, accumulator, finisher)
142
- Collector.shortable(identity, interruptor, accumulator, finisher)
186
+ // Nota: El flujo aún no se ha ejecutado, necesita conversión a Collectable para operaciones terminales
143
187
  ```
144
188
 
145
- Pero normalmente los usarás a través de métodos de alto nivel en las clases `Collectable`.
146
-
147
- ---
189
+ #### Operaciones Terminales de Flujos
148
190
 
149
- ### 6. `Collectable<E>` (clase abstracta)
191
+ | Método | Tipo de Retorno | Descripción | Características de Rendimiento |
192
+ |------|----------|------|----------|
193
+ | `toOrdered()` | `OrderedCollectable<E>` | Convertir a colección ordenada | Operación de ordenación, menor rendimiento |
194
+ | `toUnordered()` | `UnorderedCollectable<E>` | Convertir a colección desordenada | Más rápido, sin ordenación |
195
+ | `toWindow()` | `WindowCollectable<E>` | Convertir a colección de ventana | Operación de ordenación, menor rendimiento |
196
+ | `toNumericStatistics()` | `Statistics<E, number>` | Análisis estadístico numérico | Operación de ordenación, menor rendimiento |
197
+ | `toBigintStatistics()` | `Statistics<E, bigint>` | Análisis estadístico de big integer | Operación de ordenación, menor rendimiento |
198
+ | `sorted()` | `OrderedCollectable<E>` | Ordenación natural | Anula resultados de redirección |
199
+ | `sorted(comparator)` | `OrderedCollectable<E>` | Ordenación personalizada | Anula resultados de redirección |
150
200
 
151
- Clase base para:
152
-
153
- - `OrderedCollectable<E>` Resultados ordenados
154
- - `UnorderedCollectable<E>` — Sin ordenar, el más rápido
155
- - `WindowCollectable<E>` — Ventanas deslizantes
156
- - `Statistics<E, D>` — Estadísticas agregadas
201
+ **Suplemento de Ejemplo de Código:**
202
+ ```typescript
203
+ import { from } from 'semantic-typescript';
157
204
 
158
- #### Métodos comunes (heredados):
205
+ const semanticStream = from([5, 2, 8, 1, 9, 3, 7, 4, 6]);
159
206
 
160
- | Método | Descripción | Ejemplo |
161
- |--------|-------------|---------|
162
- | `count()` | Contar elementos | `.count()` |
163
- | `toArray()` | Convertir a Array | `.toArray()` |
164
- | `toSet()` | Convertir a Set | `.toSet()` |
165
- | `toMap(k, v)` | Convertir a Map | `.toMap(x => x.id, x => x)` |
166
- | `group(k)` | Agrupar por clave | `.group(x => x.category)` |
167
- | `findAny()` | Encontrar cualquier elemento (Optional) | `.findAny()` |
168
- | `findFirst()` | Encontrar el primer elemento (Optional) | `.findFirst()` |
169
- | `reduce(...)` | Reducción personalizada | `.reduce((a,b) => a + b, 0)` |
207
+ // Convertir a colección ordenada (menor rendimiento)
208
+ const ordered = semanticStream.toOrdered();
170
209
 
171
- ---
210
+ // Convertir a colección desordenada (más rápido)
211
+ const unordered = semanticStream.toUnordered();
172
212
 
173
- ### 7. `OrderedCollectable<E>` — Datos ordenados
213
+ // Ordenación natural
214
+ const sortedNatural = semanticStream.sorted();
174
215
 
175
- Si deseas que los elementos estén **ordenados automáticamente**, usa esta clase.
216
+ // Ordenación personalizada
217
+ const sortedCustom = semanticStream.sorted((a, b) => b - a); // Orden descendente
176
218
 
177
- Acepta un **comparador personalizado** o el orden natural.
219
+ // Convertir a objeto estadístico
220
+ const stats = semanticStream.toNumericStatistics();
178
221
 
179
- ```typescript
180
- const sorted = new OrderedCollectable(stream);
181
- const customSorted = new OrderedCollectable(stream, (a, b) => b - a);
222
+ // Nota: Debe llamar a los métodos anteriores a través de la instancia Semantic para obtener Collectable antes de usar métodos terminales
182
223
  ```
183
224
 
184
- 🔒 **El orden está garantizado.**
185
-
186
- ---
225
+ ### Collector<E, A, R> - Colector de Datos
187
226
 
188
- ### 8. `UnorderedCollectable<E>` Sin ordenar (🚀 Más rápido)
227
+ Los colectores se utilizan para agregar datos de flujos en estructuras específicas.
189
228
 
190
- Si **no te importa el orden** y buscas el **mejor rendimiento**, usa:
229
+ | Método | Descripción | Escenario de Uso |
230
+ |------|------|----------|
231
+ | `collect(generator)` | Ejecutar recolección de datos | Operación terminal de flujo |
232
+ | `static full(identity, accumulator, finisher)` | Crear colector completo | Requiere procesamiento completo |
233
+ | `static shortable(identity, interruptor, accumulator, finisher)` | Crear colector interrumpible | Puede terminar temprano |
191
234
 
235
+ **Suplemento de Ejemplo de Código:**
192
236
  ```typescript
193
- const unordered = new UnorderedCollectable(stream);
194
- // O
195
- const fastest = semanticStream.toUnordered();
237
+ import { Collector } from 'semantic-typescript';
238
+
239
+ // Crear colector personalizado
240
+ const sumCollector = Collector.full(
241
+ () => 0, // Valor inicial
242
+ (acc, value) => acc + value, // Acumulador
243
+ result => result // Función finalizadora
244
+ );
245
+
246
+ // Usar colector (requiere conversión de Semantic a Collectable primero)
247
+ const numbers = from([1, 2, 3, 4, 5]);
248
+ const sum = numbers.toUnordered().collect(sumCollector); // 15
196
249
  ```
197
250
 
198
- **No se ejecuta ningún algoritmo de ordenamiento**
199
- ✅ **Mejor rendimiento cuando el orden no importa**
200
-
201
- ---
251
+ ### Collectable<E> - Clase Abstracta de Datos Colectables
202
252
 
203
- ### 9. `Statistics<E, D>` Análisis estadístico
253
+ Proporciona métodos ricos de agregación y transformación de datos. **Nota: Primero debe obtener una instancia Collectable llamando a sorted(), toOrdered(), etc. a través de la instancia Semantic antes de usar los siguientes métodos.**
204
254
 
205
- Clase abstracta para analizar datos numéricos.
255
+ #### Operaciones de Consulta de Datos
206
256
 
207
- #### Subclases:
257
+ | Método | Tipo de Retorno | Descripción | Ejemplo |
258
+ |------|----------|------|------|
259
+ | `anyMatch(predicate)` | `boolean` | Si algún elemento coincide | `anyMatch(x => x > 0)` |
260
+ | `allMatch(predicate)` | `boolean` | Si todos los elementos coinciden | `allMatch(x => x > 0)` |
261
+ | `count()` | `bigint` | Estadísticas de conteo de elementos | `count()` → `5n` |
262
+ | `isEmpty()` | `boolean` | Si el flujo está vacío | `isEmpty()` |
263
+ | `findAny()` | `Optional<E>` | Encontrar cualquier elemento | `findAny()` |
264
+ | `findFirst()` | `Optional<E>` | Encontrar primer elemento | `findFirst()` |
265
+ | `findLast()` | `Optional<E>` | Encontrar último elemento | `findLast()` |
208
266
 
209
- - `NumericStatistics<E>` Para valores `number`
210
- - `BigIntStatistics<E>` — Para valores `bigint`
211
-
212
- ##### Métodos estadísticos comunes:
267
+ **Suplemento de Ejemplo de Código:**
268
+ ```typescript
269
+ import { from } from 'semantic-typescript';
213
270
 
214
- | Método | Descripción | Ejemplo |
215
- |--------|-------------|---------|
216
- | `mean()` | Media | `.mean()` |
217
- | `median()` | Mediana | `.median()` |
218
- | `mode()` | Moda (valor más frecuente) | `.mode()` |
219
- | `minimum()` | Mínimo | `.minimum()` |
220
- | `maximum()` | Máximo | `.maximum()` |
221
- | `range()` | Rango (máximo - mínimo) | `.range()` |
222
- | `variance()` | Varianza | `.variance()` |
223
- | `standardDeviation()` | Desviación estándar | `.standardDeviation()` |
224
- | `summate()` | Suma total | `.summate()` |
225
- | `quantile(q)` | Valor en el percentil q (0–1) | `.quantile(0.5)` → mediana |
226
- | `frequency()` | Frecuencia como Map | `.frequency()` |
271
+ const numbers = from([1, 2, 3, 4, 5]);
227
272
 
228
- ---
273
+ // Debe convertir a Collectable antes de usar métodos terminales
274
+ const collectable = numbers.toUnordered();
229
275
 
230
- ## 🧪 Ejemplo completo
276
+ // Operaciones de consulta de datos
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(); // Cualquier elemento
283
+ ```
231
284
 
285
+ #### Operaciones de Agregación de Datos
286
+
287
+ | Método | Tipo de Retorno | Descripción | Complejidad |
288
+ |------|----------|------|--------|
289
+ | `group(classifier)` | `Map<K, E[]>` | Agrupar por clasificador | O(n) |
290
+ | `groupBy(keyExtractor, valueExtractor)` | `Map<K, V[]>` | Agrupar por extractores de clave-valor | O(n) |
291
+ | `join()` | `string` | Unir como cadena | O(n) |
292
+ | `join(delimiter)` | `string` | Unir con delimitador | O(n) |
293
+ | `partition(count)` | `E[][]` | Particionar por conteo | O(n) |
294
+ | `partitionBy(classifier)` | `E[][]` | Particionar por clasificador | O(n) |
295
+ | `reduce(accumulator)` | `Optional<E>` | Operación de reducción | O(n) |
296
+ | `reduce(identity, accumulator)` | `E` | Reducción con identidad | O(n) |
297
+ | `toArray()` | `E[]` | Convertir a array | O(n) |
298
+ | `toMap(keyExtractor, valueExtractor)` | `Map<K, V>` | Convertir a Map | O(n) |
299
+ | `toSet()` | `Set<E>` | Convertir a Set | O(n) |
300
+
301
+ **Suplemento de Ejemplo de Código:**
232
302
  ```typescript
233
- import { from, toUnordered, toOrdered, sorted, NumericStatistics } from 'semantic-typescript';
234
-
235
- // Datos de ejemplo
236
- const numbers = from([10, 2, 8, 4, 5, 6]);
237
-
238
- // 🚀 Más rápido: sin ordenar
239
- const fastest = numbers.toUnordered();
240
- console.log(fastest.toArray()); // Ej: [10, 2, 8, 4, 5, 6] (orden original)
241
-
242
- // 🔢 Orden natural
243
- const ordered = numbers.sorted();
244
- console.log(ordered.toArray()); // [2, 4, 5, 6, 8, 10]
245
-
246
- // 📊 Estadísticas
247
- const stats = new NumericStatistics(numbers);
248
- console.log('Media:', stats.mean());
249
- console.log('Mediana:', stats.median());
250
- console.log('Moda:', stats.mode());
251
- console.log('Rango:', stats.range());
252
- console.log('Desviación estándar:', stats.standardDeviation());
303
+ import { from } from 'semantic-typescript';
304
+
305
+ const people = from([
306
+ { name: "Alice", age: 25, city: "New York" },
307
+ { name: "Bob", age: 30, city: "London" },
308
+ { name: "Charlie", age: 25, city: "New York" }
309
+ ]);
310
+
311
+ // Debe convertir a Collectable antes de usar operaciones de agregación
312
+ const collectable = people.toUnordered();
313
+
314
+ // Operaciones de agrupación
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
+ // Convertir a colecciones
325
+ const array = collectable.toArray(); // Array original
326
+ const set = collectable.toSet(); // Colección Set
327
+ const map = collectable.toMap(
328
+ person => person.name,
329
+ person => person.age
330
+ ); // Map { "Alice" => 25, "Bob" => 30, "Charlie" => 25 }
331
+
332
+ // Operaciones de reducción
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
+ ### Implementaciones Específicas de Colectores
256
338
 
257
- ## 🛠️ Funciones útiles
339
+ #### UnorderedCollectable<E>
340
+ - **Características**: Colector más rápido, sin ordenación
341
+ - **Escenarios de Uso**: Orden no importante, máximo rendimiento deseado
342
+ - **Métodos**: Hereda todos los métodos de Collectable
258
343
 
259
- La librería también exporta varias **guardas de tipo (type guards)** y **herramientas de comparación**:
344
+ #### OrderedCollectable<E>
345
+ - **Características**: Garantiza orden de elementos, menor rendimiento
346
+ - **Escenarios de Uso**: Requieren resultados ordenados
347
+ - **Métodos Especiales**: Hereda todos los métodos, mantiene estado de orden interno
260
348
 
261
- | Función | Propósito |
262
- |--------|-----------|
263
- | `isString(x)` | Guarda de tipo para `string` |
264
- | `isNumber(x)` | Guarda de tipo para `number` |
265
- | `isBoolean(x)` | Guarda de tipo para `boolean` |
266
- | `isIterable(x)` | Comprueba si un objeto es iterable |
267
- | `useCompare(a, b)` | Función de comparación universal |
268
- | `useRandom(x)` | Generador de números aleatorios (divertido) |
349
+ #### WindowCollectable<E>
350
+ - **Características**: Soporta operaciones de ventana deslizante
351
+ - **Escenarios de Uso**: Análisis de datos de series temporales
352
+ - **Métodos Especiales**:
353
+ - `slide(size, step)` - Ventana deslizante
354
+ - `tumble(size)` - Ventana de tumble
269
355
 
270
- ---
356
+ **Suplemento de Ejemplo de Código:**
357
+ ```typescript
358
+ import { from } from 'semantic-typescript';
271
359
 
272
- ## 🧩 Avanzado: Generadores personalizados y ventanas
360
+ const data = from([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
273
361
 
274
- Puedes crear **generadores personalizados** para flujos controlados o infinitos:
362
+ // Colector desordenado (más rápido)
363
+ const unordered = data.toUnordered();
364
+ const unorderedArray = unordered.toArray(); // Puede mantener orden original [1, 2, 3, ...]
275
365
 
276
- ```typescript
277
- const gen = (accept: BiConsumer<number, bigint>, interrupt: Predicate<number>) => {
278
- for (let i = 0; i < 10; i++) {
279
- accept(i, BigInt(i));
280
- if (i === 5) interrupt(i);
281
- }
282
- };
283
-
284
- const s = new Semantic(gen);
285
- ```
366
+ // Colector ordenado
367
+ const ordered = data.toOrdered();
368
+ const orderedArray = ordered.toArray(); // Orden garantizado [1, 2, 3, ...]
286
369
 
287
- O usar **ventanas deslizantes (sliding windows)**:
370
+ // Colector de ventana
371
+ const windowed = data.toWindow();
372
+ const slidingWindows = windowed.slide(3n, 2n); // Tamaño de ventana 3, paso 2
373
+ // Ventana 1: [1, 2, 3], Ventana 2: [3, 4, 5], Ventana 3: [5, 6, 7], ...
288
374
 
289
- ```typescript
290
- const windowed = ordered.slide(3n, 2n); // Ventanas de tamaño 3, salto de 2
375
+ const tumblingWindows = windowed.tumble(4n); // Ventana de tumble tamaño 4
376
+ // Ventana 1: [1, 2, 3, 4], Ventana 2: [5, 6, 7, 8], ...
291
377
  ```
292
378
 
293
- ---
294
-
295
- ## 📄 Licencia
296
-
297
- Este proyecto está bajo la licencia **MIT** — libre para uso comercial y personal.
379
+ ### Statistics<E, D> - Análisis Estadístico
380
+
381
+ Clase base de análisis estadístico que proporciona métodos ricos de cálculo estadístico. **Nota: Primero debe obtener una instancia Statistics llamando a toNumericStatistics() o toBigIntStatistics() a través de la instancia Semantic antes de usar los siguientes métodos.**
382
+
383
+ #### Operaciones de Cálculo Estadístico
384
+
385
+ | Método | Tipo de Retorno | Descripción | Complejidad de Algoritmo |
386
+ |------|----------|------|------------|
387
+ | `maximum()` | `Optional<E>` | Valor máximo | O(n) |
388
+ | `minimum()` | `Optional<E>` | Valor mínimo | O(n) |
389
+ | `range()` | `D` | Rango (max-min) | O(n) |
390
+ | `variance()` | `D` | Varianza | O(n) |
391
+ | `standardDeviation()` | `D` | Desviación estándar | O(n) |
392
+ | `mean()` | `D` | Valor medio | O(n) |
393
+ | `median()` | `D` | Valor mediano | O(n log n) |
394
+ | `mode()` | `D` | Valor modal | O(n) |
395
+ | `frequency()` | `Map<D, bigint>` | Distribución de frecuencia | O(n) |
396
+ | `summate()` | `D` | Sumatoria | O(n) |
397
+ | `quantile(quantile)` | `D` | Cuantil | O(n log n) |
398
+ | `interquartileRange()` | `D` | Rango intercuartílico | O(n log n) |
399
+ | `skewness()` | `D` | Asimetría | O(n) |
400
+ | `kurtosis()` | `D` | Curtosis | O(n) |
401
+
402
+ **Suplemento de Ejemplo de Código:**
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
+ // Debe convertir a objeto estadístico antes de usar métodos estadísticos
409
+ const stats = numbers.toNumericStatistics();
410
+
411
+ // Estadísticas básicas
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
+ // Estadísticas avanzadas
421
+ const variance = stats.variance(); // 8.25
422
+ const stdDev = stats.standardDeviation(); // 2.872
423
+ const mode = stats.mode(); // Cualquier valor (ya que todos aparecen una vez)
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
+ // Distribución de frecuencia
429
+ const freq = stats.frequency(); // Map {1 => 1n, 2 => 1n, ...}
430
+ ```
298
431
 
299
- ---
432
+ #### Clases Específicas de Implementación Estadística
300
433
 
301
- ## 🙌 Contribuir
434
+ **NumericStatistics<E>**
435
+ - Maneja análisis estadístico de tipo number
436
+ - Todos los cálculos estadísticos retornan tipo number
302
437
 
303
- ¡Pull requests, issues y sugerencias son bienvenidos!
438
+ **BigIntStatistics<E>**
439
+ - Maneja análisis estadístico de tipo bigint
440
+ - Todos los cálculos estadísticos retornan tipo bigint
304
441
 
305
- ---
442
+ **Suplemento de Ejemplo de Código:**
443
+ ```typescript
444
+ import { from } from 'semantic-typescript';
306
445
 
307
- ## 🚀 Resumen rápido
446
+ // Estadísticas numéricas
447
+ const numberData = from([10, 20, 30, 40, 50]);
448
+ const numericStats = numberData.toNumericStatistics();
308
449
 
309
- | Tarea | Método |
310
- |-------|--------|
311
- | Manejar nulos con seguridad | `Optional<T>` |
312
- | Crear un flujo | `from([...])`, `range()`, `fill()` |
313
- | Transformar datos | `map()`, `filter()` |
314
- | Ordenar datos | `sorted()`, `toOrdered()` |
315
- | Sin ordenar (más rápido) | `toUnordered()` ✅ |
316
- | Agrupar / Agregar | `toMap()`, `group()`, `Collector` |
317
- | Estadísticas | `NumericStatistics`, `mean()`, `median()`, etc. |
450
+ console.log(numericStats.mean()); // 30
451
+ console.log(numericStats.summate()); // 150
318
452
 
319
- ---
453
+ // Estadísticas de big integer
454
+ const bigintData = from([100n, 200n, 300n, 400n, 500n]);
455
+ const bigintStats = bigintData.toBigIntStatistics();
320
456
 
321
- ## 🔗 Enlaces
457
+ console.log(bigintStats.mean()); // 300n
458
+ console.log(bigintStats.summate()); // 1500n
322
459
 
323
- - 📦 npm: https://www.npmjs.com/package/semantic-typescript
324
- - 🐙 GitHub: https://github.com/eloyhere/semantic-typescript
325
- - 📘 Documentación: Ver código fuente / definiciones de tipo
460
+ // Estadísticas usando funciones mapeadoras
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
- **Disfruta del procesamiento de datos funcional, seguro y compuesto en TypeScript.** 🚀
473
+ ## Ejemplo Completo de Uso
330
474
 
331
- ---
475
+ ```typescript
476
+ import { from, validate, invalidate } from 'semantic-typescript';
477
+
478
+ // 1. Crear flujo de datos
479
+ const rawData = [5, 2, 8, 1, null, 9, 3, undefined, 7, 4, 6];
480
+ const semanticStream = from(rawData);
481
+
482
+ // 2. Pipeline de procesamiento de flujo
483
+ const processedStream = semanticStream
484
+ .filter(val => validate(val)) // Filtrar null y undefined
485
+ .map(val => val! * 2) // Multiplicar cada valor por 2 (usando ! porque validate asegura no vacío)
486
+ .distinct(); // Eliminar duplicados
487
+
488
+ // 3. Convertir a Collectable y usar operaciones terminales
489
+ const collectable = processedStream.toUnordered();
490
+
491
+ // 4. Validación de datos y uso
492
+ if (!collectable.isEmpty()) {
493
+ const results = collectable
494
+ .filter(x => x > 5) // Filtrar nuevamente
495
+ .toArray(); // Convertir a array
496
+
497
+ console.log("Resultados del procesamiento:", results); // [16, 18, 14, 8, 12]
498
+
499
+ // Información estadística
500
+ const stats = processedStream.toNumericStatistics();
501
+ console.log("Valor medio:", stats.mean()); // 11.2
502
+ console.log("Suma total:", stats.summate()); // 56
503
+ }
504
+
505
+ // 5. Manejar datos potencialmente inválidos
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("Datos válidos:", validData); // [1, 3, 4]
511
+ console.log("Datos inválidos:", invalidData); // [null, null]
512
+ ```
332
513
 
333
- **Recuerda:**
334
- - `toUnordered()` → **Sin ordenar, más rápido**
335
- - Los demás (`sorted()`, `toOrdered()`, etc.) **Ordenan los datos**
514
+ ## Resumen de Reglas Importantes de Uso
515
+
516
+ 1. **Crear Flujo**: Usar métodos de fábrica `from()`, `range()`, `fill()`, etc. para crear instancias Semantic
517
+ 2. **Transformación de Flujo**: Llamar métodos `map()`, `filter()`, `distinct()`, etc. en instancias Semantic
518
+ 3. **Convertir a Collectable**: Debe llamar a uno de los siguientes métodos a través de la instancia Semantic:
519
+ - `toOrdered()` - Colector ordenado
520
+ - `toUnordered()` - Colector desordenado (más rápido)
521
+ - `toWindow()` - Colector de ventana
522
+ - `toNumericStatistics()` - Estadísticas numéricas
523
+ - `toBigIntStatistics()` - Estadísticas de big integer
524
+ - `sorted()` - Ordenación natural
525
+ - `sorted(comparator)` - Ordenación personalizada
526
+ 4. **Operaciones Terminales**: Llamar métodos terminales `toArray()`, `count()`, `summate()`, etc. en instancias Collectable
527
+ 5. **Validación de Datos**: Usar `validate()` para asegurar que los datos no son null/undefined, usar `invalidate()` para verificar datos inválidos
528
+
529
+ Este diseño garantiza seguridad de tipos y optimización de rendimiento mientras proporciona funcionalidad rica de procesamiento de flujos.