semantic-typescript 0.5.3 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/asynchronous/collector.d.ts +231 -0
- package/dist/asynchronous/collector.js +800 -0
- package/dist/asynchronous/semantic.d.ts +257 -0
- package/dist/asynchronous/semantic.js +1853 -0
- package/dist/factory.d.ts +71 -37
- package/dist/factory.js +443 -262
- package/dist/guard.d.ts +24 -14
- package/dist/guard.js +73 -19
- package/dist/hook.d.ts +6 -6
- package/dist/hook.js +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +2 -2
- package/dist/optional.d.ts +2 -2
- package/dist/symbol.d.ts +19 -10
- package/dist/symbol.js +19 -10
- package/dist/synchronous/collector.d.ts +232 -0
- package/dist/{collector.js → synchronous/collector.js} +160 -151
- package/dist/{semantic.d.ts → synchronous/semantic.d.ts} +111 -120
- package/dist/{semantic.js → synchronous/semantic.js} +299 -337
- package/dist/utility.d.ts +7 -1
- package/dist/utility.js +1 -0
- package/package.json +1 -1
- package/readme.cn.md +158 -697
- package/readme.de.md +163 -432
- package/readme.es.md +163 -433
- package/readme.fr.md +162 -444
- package/readme.jp.md +162 -442
- package/readme.kr.md +161 -430
- package/readme.md +157 -1009
- package/readme.ru.md +161 -426
- package/readme.tw.md +161 -436
- package/dist/collector.d.ts +0 -236
- package/dist/main.d.ts +0 -1
- package/dist/main.js +0 -4
- package/dist/map.d.ts +0 -76
- package/dist/map.js +0 -245
- package/dist/node.d.ts +0 -182
- package/dist/node.js +0 -918
- package/dist/set.d.ts +0 -19
- package/dist/set.js +0 -65
- package/dist/tree.d.ts +0 -82
- package/dist/tree.js +0 -257
package/readme.kr.md
CHANGED
|
@@ -1,478 +1,209 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Semantic-TypeScript: 패러다임을 바꾸는 스트림 처리 라이브러리
|
|
2
2
|
|
|
3
3
|
## 소개
|
|
4
|
+
Semantic-TypeScript는 스트림 처리 기술의 중요한 발전을 나타내며, JavaScript GeneratorFunctions, Java Streams, 데이터베이스 인덱싱 패러다임의 가장 효과적인 개념들을 종합했습니다. 그 핵심 설계 원칙은 정교한 지연 평가(lazy evaluation)와 지능형 인덱싱을 통해 매우 효율적인 데이터 처리 파이프라인을 구축하는 데 중점을 두고 있습니다. 이 라이브러리는 현대적인 TypeScript 및 JavaScript 개발을 위해 특별히 설계된 엄격한 타입 안전성과 함수형 순수성을 갖춘 스트리밍 작업 경험을 제공합니다.
|
|
4
5
|
|
|
5
|
-
|
|
6
|
+
기존의 동기식 처리 아키텍처와 대조적으로, Semantic-TypeScript는 동기식(Iterable) 및 비동기식(AsyncIterable) 데이터 소스를 모두 우아하게 처리하는 통합 모델을 구현합니다. 스트림 생성 중 데이터의 흐름과 종료는 콜백 메커니즘에 의해 정밀하게 제어되어 라이브러리가 예외적인 우아함으로 다음을 처리할 수 있게 합니다:
|
|
7
|
+
- 결정론적 제어가 가능한 실시간 데이터 스트림(DOM 이벤트, WebSockets, 간격)
|
|
8
|
+
- 메모리 효율적이고 지연 평가되는 파이프라인을 통한 대규모 데이터셋
|
|
9
|
+
- 유창하고 선언적인 API를 통한 복잡한 데이터 변환
|
|
6
10
|
|
|
7
|
-
|
|
11
|
+
이 라이브러리의 혁신적인 접근 방식은 개발자가 데이터 시퀀스와 상호작용하는 방식을 근본적으로 재구상하며, 단일하고 응집력 있는 패키지 내에서 전례 없는 성능 특성과 개발자 인체공학을 모두 제공합니다.
|
|
8
12
|
|
|
9
|
-
##
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
```
|
|
13
|
+
## 핵심 철학: 정의와 실행의 분리
|
|
14
|
+
Semantic-TypeScript의 중요한 아키텍처적 통찰은 스트림의 정의와 실행을 명확하게 분리하는 것입니다:
|
|
15
|
+
- **Semantic<E>**: 데이터 변환 파이프라인의 불변(immutable)하고 지연 평가(lazy)되는 설계도입니다. 어떤 연산(filter, map 등)이 수행될지 정의합니다.
|
|
16
|
+
- **Collectable<E>**: 스트림의 구체화되고 실행 가능한 뷰입니다. Semantic에서 얻어지며, 파이프라인을 실행하고 결과를 생성하기 위한 모든 최종 연산(collect, forEach 등)을 제공합니다.
|
|
14
17
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
| 타입 | 설명 |
|
|
18
|
-
|------|-------------|
|
|
19
|
-
| `Invalid<T>` | `null` 또는 `undefined`에서 확장된 타입 |
|
|
20
|
-
| `Valid<T>` | `null`과 `undefined`를 제외한 타입 |
|
|
21
|
-
| `MaybeInvalid<T>` | `null` 또는 `undefined`일 수 있는 타입 |
|
|
22
|
-
| `Primitive` | 기본 타입의 집합 |
|
|
23
|
-
| `MaybePrimitive<T>` | 기본 타입일 수 있는 타입 |
|
|
24
|
-
| `OptionalSymbol` | `Optional` 클래스의 심볼 식별자 |
|
|
25
|
-
| `SemanticSymbol` | `Semantic` 클래스의 심볼 식별자 |
|
|
26
|
-
| `CollectorsSymbol` | `Collector` 클래스의 심볼 식별자 |
|
|
27
|
-
| `CollectableSymbol` | `Collectable` 클래스의 심볼 식별자 |
|
|
28
|
-
| `OrderedCollectableSymbol` | `OrderedCollectable` 클래스의 심볼 식별자 |
|
|
29
|
-
| `WindowCollectableSymbol` | `WindowCollectable` 클래스의 심볼 식별자 |
|
|
30
|
-
| `StatisticsSymbol` | `Statistics` 클래스의 심볼 식별자 |
|
|
31
|
-
| `NumericStatisticsSymbol` | `NumericStatistics` 클래스의 심볼 식별자 |
|
|
32
|
-
| `BigIntStatisticsSymbol` | `BigIntStatistics` 클래스의 심볼 식별자 |
|
|
33
|
-
| `UnorderedCollectableSymbol` | `UnorderedCollectable` 클래스의 심볼 식별자 |
|
|
34
|
-
|
|
35
|
-
## 함수 지향 인터페이스
|
|
36
|
-
|
|
37
|
-
| 인터페이스 | 설명 |
|
|
38
|
-
|-----------|-------------|
|
|
39
|
-
| `Runnable` | 매개변수가 없고 반환값도 없는 함수 |
|
|
40
|
-
| `Supplier<R>` | 매개변수가 없고 `R`을 반환하는 함수 |
|
|
41
|
-
| `Functional<T, R>` | 단일 매개변수 변환 함수 |
|
|
42
|
-
| `BiFunctional<T, U, R>` | 두 개의 매개변수 변환 함수 |
|
|
43
|
-
| `TriFunctional<T, U, V, R>` | 세 개의 매개변수 변환 함수 |
|
|
44
|
-
| `Predicate<T>` | 단일 매개변수 조건 함수 |
|
|
45
|
-
| `BiPredicate<T, U>` | 두 개의 매개변수 조건 함수 |
|
|
46
|
-
| `TriPredicate<T, U, V>` | 세 개의 매개변수 조건 함수 |
|
|
47
|
-
| `Consumer<T>` | 단일 매개변수 소비자 함수 |
|
|
48
|
-
| `BiConsumer<T, U>` | 두 개의 매개변수 소비자 함수 |
|
|
49
|
-
| `TriConsumer<T, U, V>` | 세 개의 매개변수 소비자 함수 |
|
|
50
|
-
| `Comparator<T>` | 두 개의 매개변수 비교 함수 |
|
|
51
|
-
| `Generator<T>` | 생성자 함수(핵심 및 기반) |
|
|
18
|
+
이러한 분리는 깔끔한 멘탈 모델을 강제하고, 불필요한 정렬을 건너뛰어 최대 속도를 내는 UnorderedCollectable을 선택하는 것과 같은 강력한 최적화를 가능하게 합니다.
|
|
52
19
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
let predicate: Predicate<number> = (n: number): boolean => n > 0;
|
|
56
|
-
let mapper: Functional<string, number> = (text: string): number => text.length;
|
|
57
|
-
let comparator: Comparator<number> = (a: number, b: number): number => a - b;
|
|
58
|
-
```
|
|
59
|
-
|
|
60
|
-
## 타입 가드
|
|
61
|
-
|
|
62
|
-
| 함수 | 설명 | 시간 복잡도 | 공간 복잡도 |
|
|
63
|
-
|------|------|------------|------------|
|
|
64
|
-
| `validate<T>(t: MaybeInvalid<T>): t is T` | 값이 null이나 undefined가 아닌지 검증 | O(1) | O(1) |
|
|
65
|
-
| `invalidate<T>(t: MaybeInvalid<T>): t is null \| undefined` | 값이 null이나 undefined인지 검증 | O(1) | O(1) |
|
|
66
|
-
| `isBoolean(t: unknown): t is boolean` | boolean인지 확인 | O(1) | O(1) |
|
|
67
|
-
| `isString(t: unknown): t is string` | 문자열인지 확인 | O(1) | O(1) |
|
|
68
|
-
| `isNumber(t: unknown): t is number` | 숫자인지 확인 | O(1) | O(1) |
|
|
69
|
-
| `isFunction(t: unknown): t is Function` | 함수인지 확인 | O(1) | O(1) |
|
|
70
|
-
| `isObject(t: unknown): t is object` | 객체인지 확인 | O(1) | O(1) |
|
|
71
|
-
| `isSymbol(t: unknown): t is symbol` | 심볼인지 확인 | O(1) | O(1) |
|
|
72
|
-
| `isBigint(t: unknown): t is bigint` | BigInt인지 확인 | O(1) | O(1) |
|
|
73
|
-
| `isPrimitive(t: unknown): t is Primitive` | 기본 타입인지 확인 | O(1) | O(1) |
|
|
74
|
-
| `isIterable(t: unknown): t is Iterable<unknown>` | 반복 가능한 객체인지 확인 | O(1) | O(1) |
|
|
75
|
-
| `isOptional(t: unknown): t is Optional<unknown>` | Optional 인스턴스인지 확인 | O(1) | O(1) |
|
|
76
|
-
| `isSemantic(t: unknown): t is Semantic<unknown>` | Semantic 인스턴스인지 확인 | O(1) | O(1) |
|
|
77
|
-
| `isCollector(t: unknown): t is Collector<unknown, unknown, unknown>` | Collector 인스턴스인지 확인 | O(1) | O(1) |
|
|
78
|
-
| `isCollectable(t: unknown): t is Collectable<unknown>` | Collectable 인스턴스인지 확인 | O(1) | O(1) |
|
|
79
|
-
| `isOrderedCollectable(t: unknown): t is OrderedCollectable<unknown>` | OrderedCollectable 인스턴스인지 확인 | O(1) | O(1) |
|
|
80
|
-
| `isWindowCollectable(t: unknown): t is WindowCollectable<unknown>` | WindowCollectable 인스턴스인지 확인 | O(1) | O(1) |
|
|
81
|
-
| `isUnorderedCollectable(t: unknown): t is UnorderedCollectable<unknown>` | UnorderedCollectable 인스턴스인지 확인 | O(1) | O(1) |
|
|
82
|
-
| `isStatistics(t: unknown): t is Statistics<unknown, number \| bigint>` | Statistics 인스턴스인지 확인 | O(1) | O(1) |
|
|
83
|
-
| `isNumericStatistics(t: unknown): t is NumericStatistics<unknown>` | NumericStatistics 인스턴스인지 확인 | O(1) | O(1) |
|
|
84
|
-
| `isBigIntStatistics(t: unknown): t is BigIntStatistics<unknown>` | BigIntStatistics 인스턴스인지 확인 | O(1) | O(1) |
|
|
85
|
-
| `isPromise(t: unknown): t is Promise<unknown>` | Promise 객체인지 확인 | O(1) | O(1) |
|
|
86
|
-
| `isAsync(t: unknown): t is AsyncFunction` | AsyncFunction인지 확인 | O(1) | O(1) |
|
|
87
|
-
|
|
88
|
-
```typescript
|
|
89
|
-
// 타입 가드 사용 예
|
|
90
|
-
let value: unknown = "hello";
|
|
20
|
+
## Semantic-TypeScript를 선택해야 하는 이유
|
|
21
|
+
데이터 스트림 처리를 위한 적절한 라이브러리를 선택하는 것은 성능, 타입 안전성, 표현력 사이의 균형을 맞추는 것을 포함합니다. Semantic-TypeScript는 이러한 모든 차원에서 탁월한 성능을 발휘하도록 설계되었습니다.
|
|
91
22
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
}
|
|
23
|
+
### 1. 모든 데이터 시퀀스를 위한 통일되고 타입 안전한 패러다임
|
|
24
|
+
정적 배열, 실시간 이벤트, 비동기 청크 등 모든 데이터 시퀀스를 처리하기 위한 일관적이고 선언적인 API를 제공하며, TypeScript의 모든 기능을 활용하여 엔드-투-엔드 타입 안전성을 보장합니다. 이는 런타임 오류의 전체 범주를 제거하고 스트림 조작을 예측 가능하고 컴파일러 검증이 가능한 활동으로 전환합니다.
|
|
95
25
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
}
|
|
26
|
+
### 2. 지능형 지연 평가를 통한 타협 없는 성능
|
|
27
|
+
핵심은 지연 평가에 기반합니다. filter, map, flatMap과 같은 연산은 단지 처리 파이프라인을 구성할 뿐이며, 최종 연산이 호출될 때까지 어떤 작업도 수행되지 않습니다. 이는 제한(limit), anyMatch 또는 사용자 정의 중단(interrupt) 콜백을 통한 단락 평가(short-circuiting) 기능과 결합되어 처리를 조기에 중지할 수 있게 하여, 크거나 무한한 스트림에 대한 효율성을 극적으로 향상시킵니다.
|
|
99
28
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
for(let item of value){
|
|
103
|
-
console.log(item);
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
```
|
|
29
|
+
### 3. `Collector<E, A, R>` 패턴의 힘
|
|
30
|
+
Java에서 영감을 받은 Collector 패턴은 유연성의 엔진입니다. 이는 스트림 요소를 누적하는 방법의 사양을 스트림 자체의 실행으로부터 분리합니다. 라이브러리는 일상 작업을 위한 다양한 내장 컬렉터(toArray, groupBy, summate 등)를 제공하면서도, 복잡하고 재사용 가능한 축소(reduction) 로직을 직접 구현하는 것을 간단하게 만듭니다. 이는 고정된 최종 메서드 세트보다 훨씬 더 강력하고 구성 가능합니다.
|
|
107
31
|
|
|
108
|
-
|
|
32
|
+
### 4. 현대 웹 및 비동기 데이터에 대한 1급 지원
|
|
33
|
+
Semantic-TypeScript는 현대적 개발을 위해 설계되었습니다. 최신 웹 소스에 대한 기본(native) 팩토리 메서드를 제공합니다:
|
|
34
|
+
- 정적 데이터: `useFrom(iterable)`, `useRange()`
|
|
35
|
+
- 시간 기반 스트림: `useInterval()`, `useAnimationFrame()`
|
|
36
|
+
- 청크 처리된 이진 데이터: `useBlob()`
|
|
37
|
+
- 실시간 이벤트 스트림: `useWebSocket()`, `useDocument()`, `useWindow()`
|
|
109
38
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
| `useCompare<T>(t1: T, t2: T): number` | 일반 비교 함수 | O(1) | O(1) |
|
|
113
|
-
| `useRandom<T = number \| bigint>(index: T): T` | 의사 난수 생성기 | O(log n) | O(1) |
|
|
39
|
+
### 5. 기본 집계를 넘어선: 내장 통계 분석
|
|
40
|
+
단순한 합계와 평균을 넘어서세요. 라이브러리는 전용 NumericStatistics 및 BigIntStatistics 인터페이스를 제공하며, 스트림에서 직접 고급 통계 측정값(분산, 표준 편차, 중앙값, 왜도, 첨도)에 즉시 액세스할 수 있습니다. 이는 복잡한 데이터 분석을 한 줄의 코드로 바꿉니다.
|
|
114
41
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
42
|
+
### 6. 개발자 인체공학을 위해 설계됨
|
|
43
|
+
- **유창하고 연결 가능한 API**: 복잡한 데이터 파이프라인을 읽기 쉽고 순차적인 체인으로 작성
|
|
44
|
+
- **포괄적인 유틸리티 모음**: 필수 가드(isFunction, isIterable), 유틸리티(useCompare, useTraverse) 및 함수형 인터페이스 포함
|
|
45
|
+
- **Optional<T> 통합**: 값의 부재를 안전하게 모델링하여 널 포인터 문제 해결
|
|
46
|
+
- **성능 가이드**: 순서 대 속도에 대해 언제 비정렬(unordered) 컬렉션을 사용하고 언제 정렬(ordered)을 사용할지에 대한 명확한 지침
|
|
119
47
|
|
|
120
|
-
|
|
48
|
+
## 설치
|
|
49
|
+
```bash
|
|
50
|
+
npm install semantic-typescript
|
|
121
51
|
```
|
|
122
52
|
|
|
123
|
-
##
|
|
53
|
+
## 실제 적용에서의 핵심 개념
|
|
124
54
|
|
|
125
|
-
###
|
|
126
|
-
|
|
127
|
-
| 메소드 | 설명 | 시간 복잡도 | 공간 복잡도 |
|
|
128
|
-
|------|------|------------|------------|
|
|
129
|
-
| `Optional.empty<T>()` | 빈 옵셔널을 생성 | O(1) | O(1) |
|
|
130
|
-
| `Optional.of<T>(value)` | 값을 포함하는 옵셔널을 생성 | O(1) | O(1) |
|
|
131
|
-
| `Optional.ofNullable<T>(value)` | 비어있을 수 있는 옵셔널을 생성 | O(1) | O(1) |
|
|
132
|
-
| `Optional.ofNonNull<T>(value)` | 비어있지 않은 옵셔널을 생성 | O(1) | O(1) |
|
|
55
|
+
### 1. 스트림 생성 (Semantic)
|
|
56
|
+
팩토리 함수를 사용하여 다양한 소스로부터 스트림을 생성할 수 있습니다.
|
|
133
57
|
|
|
134
58
|
```typescript
|
|
135
|
-
|
|
136
|
-
let empty: Optional<number> = Optional.empty();
|
|
137
|
-
let present: Optional<number> = Optional.of(42);
|
|
138
|
-
let nullable: Optional<string> = Optional.ofNullable<string>(null);
|
|
139
|
-
let nonNull: Optional<string> = Optional.ofNonNull("hello");
|
|
140
|
-
|
|
141
|
-
present.ifPresent((val: number): void => console.log(val)); // 42 출력
|
|
142
|
-
console.log(emptyOpt.get(100)); // 100 출력
|
|
143
|
-
```
|
|
59
|
+
import { useFrom, useInterval, useDocument } from 'semantic-typescript';
|
|
144
60
|
|
|
145
|
-
|
|
61
|
+
// 정적 배열로부터
|
|
62
|
+
const staticStream = useFrom([1, 2, 3, 4, 5]);
|
|
146
63
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
64
|
+
// 비동기 제너레이터로부터
|
|
65
|
+
const asyncStream = useFrom(async function*() {
|
|
66
|
+
yield 1;
|
|
67
|
+
yield 2;
|
|
68
|
+
});
|
|
151
69
|
|
|
152
|
-
|
|
153
|
-
//
|
|
154
|
-
let numbers = from([3, 1, 4, 1, 5, 9, 2, 6, 5]);
|
|
155
|
-
|
|
156
|
-
// 성능 우선: 순서가 보장되지 않는 컬렉터 사용
|
|
157
|
-
let unordered = numbers
|
|
158
|
-
.filter((n: number): boolean => n > 3)
|
|
159
|
-
.toUnordered(); // 최고의 성능
|
|
160
|
-
|
|
161
|
-
// 정렬 필요: 순서가 보장되는 컬렉터 사용
|
|
162
|
-
let ordered = numbers.sorted();
|
|
163
|
-
|
|
164
|
-
// 요소 수 계산
|
|
165
|
-
let count = Collector.full(
|
|
166
|
-
(): number => 0, // 초기값
|
|
167
|
-
(accumulator: number, element: number): number => accumulator + element, // 누적
|
|
168
|
-
(accumulator: number): number => accumulator // 완료
|
|
169
|
-
);
|
|
170
|
-
count.collect(from([1,2,3,4,5])); // 스트림에서 카운트
|
|
171
|
-
count.collect([1,2,3,4,5]); // 반복 가능한 객체에서 카운트
|
|
172
|
-
|
|
173
|
-
let find = Collector.shortable(
|
|
174
|
-
(): Optional<number> => Optional.empty(), // 초기값
|
|
175
|
-
(element: number, index: bigint, accumulator: Optional<number>): Optional<number> => accumulator.isPresent(), // 중단
|
|
176
|
-
(accumulator: Optional<number>, element: number, index: bigint): Optional<number> => Optional.of(element), // 누적
|
|
177
|
-
(accumulator: Optional<number>): Optional<number> => accumulator // 완료
|
|
178
|
-
);
|
|
179
|
-
find.collect(from([1,2,3,4,5])); // 첫 번째 요소 찾기
|
|
180
|
-
find.collect([1,2,3,4,5]); // 첫 번째 요소 찾기
|
|
181
|
-
```
|
|
182
|
-
|
|
183
|
-
### 시맨틱 팩토리 메소드
|
|
70
|
+
// 시간 기반 스트림
|
|
71
|
+
const tickStream = useInterval(1000); // 매초마다 방출
|
|
184
72
|
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
| `animationFrame(period: number, delay: number = 0)` | 시간 기반 애니메이션 프레임 스트림을 생성 | O(1)* | O(1) |
|
|
188
|
-
| `blob(blob, chunkSize)` | Blob에서 스트림을 생성 | O(n) | O(chunkSize) |
|
|
189
|
-
| `empty<E>()` | 빈 스트림을 생성 | O(1) | O(1) |
|
|
190
|
-
| `fill<E>(element, count)` | 채워진 스트림을 생성 | O(n) | O(1) |
|
|
191
|
-
| `from<E>(iterable)` | 반복 가능한 객체에서 스트림을 생성 | O(1) | O(1) |
|
|
192
|
-
| `interval(period, delay?)` | 시간 기반 인터벌 스트림을 생성 | O(1)* | O(1) |
|
|
193
|
-
| `iterate<E>(generator)` | 생성자에서 스트림을 생성 | O(1) | O(1) |
|
|
194
|
-
| `range(start, end, step)` | 숫자 범위 스트림을 생성 | O(n) | O(1) |
|
|
195
|
-
| `websocket(websocket)` | WebSocket에서 스트림을 생성 | O(1) | O(1) |
|
|
196
|
-
|
|
197
|
-
```typescript
|
|
198
|
-
// 시맨틱 팩토리 메소드 사용 예
|
|
199
|
-
|
|
200
|
-
// Blob에서 스트림을 생성(청크 읽기)
|
|
201
|
-
blob(someBlob, 1024n)
|
|
202
|
-
.toUnordered()
|
|
203
|
-
.write(WritableStream)
|
|
204
|
-
.then(callback) // 스트림 쓰기 성공
|
|
205
|
-
.catch(callback); // 스트림 쓰기 실패
|
|
206
|
-
|
|
207
|
-
// 빈 스트림을 생성, 다른 스트림과 연결될 때까지 실행되지 않음
|
|
208
|
-
empty<string>()
|
|
209
|
-
.toUnordered()
|
|
210
|
-
.join(); // []
|
|
211
|
-
|
|
212
|
-
// 채워진 스트림을 생성
|
|
213
|
-
const filledStream = fill("hello", 3); // "hello", "hello", "hello"
|
|
214
|
-
|
|
215
|
-
// 초기 지연 2초, 실행 주기 5초의 시간 기반 스트림을 생성, 타이머 메커니즘에 기반하여 구현됩니다. 시스템 스케줄링의 정확도 제한으로 인해 시간 드리프트가 발생할 수 있습니다.
|
|
216
|
-
const intervalStream = interval(5000, 2000);
|
|
217
|
-
|
|
218
|
-
// 반복 가능한 객체에서 스트림을 생성
|
|
219
|
-
const numberStream = from([1, 2, 3, 4, 5]);
|
|
220
|
-
const stringStream = from(new Set(["Alex", "Bob"]));
|
|
221
|
-
|
|
222
|
-
// 숫자 범위 스트림을 생성
|
|
223
|
-
const rangeStream = range(1, 10, 2); // 1, 3, 5, 7, 9
|
|
224
|
-
|
|
225
|
-
// WebSocket 이벤트 스트림
|
|
226
|
-
const ws = new WebSocket("ws://localhost:8080");
|
|
227
|
-
websocket(ws)
|
|
228
|
-
.filter((event): boolean => event.type === "message") // 메시지 이벤트만 듣기
|
|
229
|
-
.toUnordered() // 이벤트는 일반적으로 순서가 없음
|
|
230
|
-
.forEach((event): void => receive(event)); // 메시지 받기
|
|
73
|
+
// DOM 이벤트 스트림 (아래의 중요한 참고사항 참조)
|
|
74
|
+
const clickStream = useDocument('click');
|
|
231
75
|
```
|
|
232
76
|
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
| 메소드 | 설명 | 시간 복잡도 | 공간 복잡도 |
|
|
236
|
-
|------|------|------------|------------|
|
|
237
|
-
| `concat(other)` | 두 개의 스트림을 연결 | O(n) | O(1) |
|
|
238
|
-
| `distinct()` | 중복을 제거 | O(n) | O(n) |
|
|
239
|
-
| `distinct(comparator)` | 비교자를 사용하여 중복을 제거 | O(n²) | O(n) |
|
|
240
|
-
| `dropWhile(predicate)` | 조건을 만족하는 요소를 버림 | O(n) | O(1) |
|
|
241
|
-
| `filter(predicate)` | 요소를 필터링 | O(n) | O(1) |
|
|
242
|
-
| `flat(mapper)` | 평탄화 맵 | O(n × m) | O(1) |
|
|
243
|
-
| `flatMap(mapper)` | 새로운 타입으로 평탄화 맵 | O(n × m) | O(1) |
|
|
244
|
-
| `limit(n)` | 요소 수 제한 | O(n) | O(1) |
|
|
245
|
-
| `map(mapper)` | 맵 변환 | O(n) | O(1) |
|
|
246
|
-
| `peek(consumer)` | 요소를 엿보기 | O(n) | O(1) |
|
|
247
|
-
| `redirect(redirector)` | 인덱스 리디렉션 | O(n) | O(1) |
|
|
248
|
-
| `reverse()` | 스트림 반전 | O(n) | O(1) |
|
|
249
|
-
| `shuffle()` | 무작위로 섞기 | O(n) | O(1) |
|
|
250
|
-
| `shuffle(mapper)` | 매퍼를 사용하여 섞기 | O(n) | O(1) |
|
|
251
|
-
| `skip(n)` | 처음 n개 요소 건너뛰기 | O(n) | O(1) |
|
|
252
|
-
| `sorted()` | 정렬 | O(n log n) | O(n) |
|
|
253
|
-
| `sorted(comparator)` | 비교자를 사용하여 정렬 | O(n log n) | O(n) |
|
|
254
|
-
| `sub(start, end)` | 서브스트림 가져오기 | O(n) | O(1) |
|
|
255
|
-
| `takeWhile(predicate)` | 조건을 만족하는 요소 가져오기 | O(n) | O(1) |
|
|
256
|
-
| `translate(offset)` | 인덱스 변환 | O(n) | O(1) |
|
|
257
|
-
| `translate(translator)` | 변환자를 사용하여 인덱스 변환 | O(n) | O(1) |
|
|
77
|
+
### 2. 스트림 변환 (중간 연산)
|
|
78
|
+
연산은 지연 평가되며 파이프라인을 정의하기 위해 체인으로 연결됩니다.
|
|
258
79
|
|
|
259
80
|
```typescript
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
.limit(3) // 3개 요소 제한
|
|
266
|
-
.toUnordered() // 순서가 보장되지 않는 컬렉터로 변환
|
|
267
|
-
.toArray(); // 배열로 변환
|
|
268
|
-
// 결과: [8, 12, 20]
|
|
269
|
-
|
|
270
|
-
// 복잡한 작업 예
|
|
271
|
-
const complexResult = range(1, 100, 1)
|
|
272
|
-
.flatMap((n: number): Semantics<number> => from([n, n * 2])) // 각 요소를 두 개로 매핑
|
|
273
|
-
.distinct() // 중복 제거
|
|
274
|
-
.shuffle() // 순서 섞기
|
|
275
|
-
.takeWhile((n: number): boolean => n < 50) // 50 미만 요소 가져오기
|
|
276
|
-
.toOrdered() // 순서가 보장되는 컬렉터로 변환
|
|
277
|
-
.toArray(); // 배열로 변환
|
|
278
|
-
```
|
|
279
|
-
|
|
280
|
-
## 시맨틱 변환 메소드
|
|
281
|
-
|
|
282
|
-
| 메소드 | 설명 | 시간 복잡도 | 공간 복잡도 |
|
|
283
|
-
|------------|------------|------------|------------|
|
|
284
|
-
| `sorted()` | 순서가 보장되는 컬렉터로 변환 | O(n log n) | O(n) |
|
|
285
|
-
| `toUnordered()` | 순서가 보장되지 않는 컬렉터로 변환 | O(1) | O(1) |
|
|
286
|
-
| `toOrdered()` | 순서가 보장되는 컬렉터로 변환 | O(1) | O(1) |
|
|
287
|
-
| `toNumericStatistics()` | 숫자 통계로 변환 | O(n) | O(1) |
|
|
288
|
-
| `toBigintStatistics()` | BigInt 통계로 변환 | O(n) | O(1) |
|
|
289
|
-
| `toWindow()` | 윈도우 컬렉터로 변환 | O(1) | O(1) |
|
|
290
|
-
| `toCollectable()` | `UnorderdCollectable`로 변환 | O(n) | O(1) |
|
|
291
|
-
| `toCollectable(mapper)` | 커스텀 컬렉터로 변환 | O(n) | O(1) |
|
|
81
|
+
const processedStream = staticStream
|
|
82
|
+
.filter(x => x % 2 === 0) // 짝수만 유지
|
|
83
|
+
.map(x => x * 10) // 10 곱하기
|
|
84
|
+
.flatMap(x => [x, x + 1]) // 각 요소를 두 개로 변환
|
|
85
|
+
.distinct(); // 중복 제거
|
|
292
86
|
|
|
293
|
-
|
|
294
|
-
// 오름차순으로 정렬된 배열로 변환
|
|
295
|
-
from([6,4,3,5,2]) // 스트림 생성
|
|
296
|
-
.sorted() // 스트림을 오름차순으로 정렬
|
|
297
|
-
.toArray(); // [2, 3, 4, 5, 6]
|
|
298
|
-
|
|
299
|
-
// 내림차순으로 정렬된 배열로 변환
|
|
300
|
-
from([6,4,3,5,2]) // 스트림 생성
|
|
301
|
-
.soted((a: number, b: number): number => b - a) // 스트림을 내림차순으로 정렬
|
|
302
|
-
.toArray(); // [6, 5, 4, 3, 2]
|
|
303
|
-
|
|
304
|
-
// 역순의 배열로 리다이렉트
|
|
305
|
-
from([6,4,3,5,2])
|
|
306
|
-
.redirect((element, index): bigint => -index) // 역순으로 리다이렉트
|
|
307
|
-
.toOrderd() // 리다이렉트된 순서 유지
|
|
308
|
-
.toArray(); // [2, 5, 3, 4, 6]
|
|
309
|
-
|
|
310
|
-
// 리다이렉션을 무시하고 역순의 배열을 얻음
|
|
311
|
-
from([6,4,3,5,2])
|
|
312
|
-
.redirect((element: number, index: bigint) => -index) // 역순으로 리다이렉트
|
|
313
|
-
.toUnorderd() // 리다이렉션된 순서 무시. 이 작업은 `redirect`, `reverse`, `shuffle` 및 `translate` 작업을 무시합니다
|
|
314
|
-
.toArray(); // [2, 5, 3, 4, 6]
|
|
315
|
-
|
|
316
|
-
// 스트림을 역순으로 배열로 변환
|
|
317
|
-
from([6, 4, 3, 5, 2])
|
|
318
|
-
.reverse() // 스트림을 역순으로 함
|
|
319
|
-
.toOrdered() // 역순을 보장함
|
|
320
|
-
.toArray(); // [2, 5, 3, 4, 6]
|
|
321
|
-
|
|
322
|
-
// 섞인 스트림을 배열로 덮어쓰기
|
|
323
|
-
from([6, 4, 3, 5, 2])
|
|
324
|
-
.shuffle() // 스트림을 섞음
|
|
325
|
-
.sorted() // 섞인 순서를 덮어씀. 이 작업은 `redirect`, `reverse`, `shuffle` 및 `translate` 작업을 덮어씀
|
|
326
|
-
.toArray(); // [2, 5, 3, 4, 6]
|
|
327
|
-
|
|
328
|
-
// 윈도우 컬렉터로 변환
|
|
329
|
-
from([6, 4, 3, 5, 2]).toWindow();
|
|
330
|
-
|
|
331
|
-
// 숫자 통계로 변환
|
|
332
|
-
from([6, 4, 3, 5, 2]).toNumericStatistics();
|
|
333
|
-
|
|
334
|
-
// BigInt 통계로 변환
|
|
335
|
-
from([6n, 4n, 3n, 5n, 2n]).toBigintStatistics();
|
|
336
|
-
|
|
337
|
-
// 데이터 수집을 위한 커스텀 컬렉터 정의
|
|
338
|
-
let customizedCollector = from([1, 2, 3, 4, 5])
|
|
339
|
-
.toCollectable((generator: Generator<E>) => new CustomizedCollector(generator));
|
|
87
|
+
// 아직 아무것도 실행되지 않았습니다
|
|
340
88
|
```
|
|
341
89
|
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
| 메소드 | 설명 | 시간 복잡도 | 공간 복잡도 |
|
|
345
|
-
|------|------|------------|------------|
|
|
346
|
-
| `anyMatch(predicate)` | 임의의 요소가 일치하는지 여부 | O(n) | O(1) |
|
|
347
|
-
| `allMatch(predicate)` | 모든 요소가 일치하는지 여부 | O(n) | O(1) |
|
|
348
|
-
| `count()` | 요소 수 | O(n) | O(1) |
|
|
349
|
-
| `isEmpty()` | 비어 있는지 여부 | O(1) | O(1) |
|
|
350
|
-
| `findAny()` | 임의의 요소 찾기 | O(n) | O(1) |
|
|
351
|
-
| `findFirst()` | 첫 번째 요소 찾기 | O(n) | O(1) |
|
|
352
|
-
| `findLast()` | 마지막 요소 찾기 | O(n) | O(1) |
|
|
353
|
-
| `forEach(action)` | 모든 요소 반복 | O(n) | O(1) |
|
|
354
|
-
| `group(classifier)` | 분류자로 그룹화 | O(n) | O(n) |
|
|
355
|
-
| `groupBy(keyExtractor, valueExtractor)` | 키-값 추출자로 그룹화 | O(n) | O(n) |
|
|
356
|
-
| `join()` | 문자열로 결합 | O(n) | O(n) |
|
|
357
|
-
| `join(delimiter)` | 구분자를 사용하여 결합 | O(n) | O(n) |
|
|
358
|
-
| `nonMatch(predicate)` | 일치하지 않는 요소가 있는지 여부 | O(n) | O(1) |
|
|
359
|
-
| `partition(count)` | 수로 분할 | O(n) | O(n) |
|
|
360
|
-
| `partitionBy(classifier)` | 분류자로 분할 | O(n) | O(n) |
|
|
361
|
-
| `reduce(accumulator)` | 축소 작업 | O(n) | O(1) |
|
|
362
|
-
| `reduce(identity, accumulator)` | 초기값을 가진 축소 | O(n) | O(1) |
|
|
363
|
-
| `toArray()` | 배열로 변환 | O(n) | O(n) |
|
|
364
|
-
| `toMap(keyExtractor, valueExtractor)` | 맵으로 변환 | O(n) | O(n) |
|
|
365
|
-
| `toSet()` | 세트로 변환 | O(n) | O(n) |
|
|
366
|
-
| `write(stream)` | 스트림에 쓰기 | O(n) | O(1) |
|
|
90
|
+
### 3. 스트림 실행 (최종 연산)
|
|
91
|
+
결과를 얻으려면 Collectable을 얻고 최종 연산을 호출해야 합니다.
|
|
367
92
|
|
|
368
93
|
```typescript
|
|
369
|
-
//
|
|
370
|
-
const
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
console.log(
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
const grouped = data.groupBy(
|
|
384
|
-
(n: number): string => (n > 5 ? "큰" : "작은"),
|
|
385
|
-
(n: number): number => n * 2
|
|
386
|
-
); // {작은: [4, 8], 큰: [12, 16, 20]}
|
|
387
|
-
|
|
388
|
-
// 축소 작업
|
|
389
|
-
const sum = data.reduce(0, (acc, n) => acc + n); // 30
|
|
390
|
-
|
|
391
|
-
// 출력 작업
|
|
392
|
-
data.join(", "); // "[2, 4, 6, 8, 10]"
|
|
94
|
+
// 성능을 위한 비정렬(unordered) collectable 얻기
|
|
95
|
+
const resultArray = await processedStream.toUnordered().toArray();
|
|
96
|
+
console.log(resultArray); // 예: [20, 21, 40, 41]
|
|
97
|
+
|
|
98
|
+
// 내장 컬렉터 사용
|
|
99
|
+
const sum = await processedStream.toUnordered().collect(useSummate());
|
|
100
|
+
console.log(sum);
|
|
101
|
+
|
|
102
|
+
// 또는 일반 collect 메서드 사용
|
|
103
|
+
const customResult = await processedStream.toOrdered().collect(
|
|
104
|
+
() => new Map<number, number>(),
|
|
105
|
+
(map, element, index) => map.set(index, element),
|
|
106
|
+
map => map
|
|
107
|
+
);
|
|
393
108
|
```
|
|
394
109
|
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
### NumericStatistics 메소드
|
|
398
|
-
|
|
399
|
-
| 메소드 | 설명 | 시간 복잡도 | 공간 복잡도 |
|
|
400
|
-
|------|------|------------|------------|
|
|
401
|
-
| `range()` | 범위 | O(n) | O(1) |
|
|
402
|
-
| `variance()` | 분산 | O(n) | O(1) |
|
|
403
|
-
| `standardDeviation()` | 표준 편차 | O(n) | O(1) |
|
|
404
|
-
| `mean()` | 평균 | O(n) | O(1) |
|
|
405
|
-
| `median()` | 중앙값 | O(n log n) | O(n) |
|
|
406
|
-
| `mode()` | 최빈값 | O(n) | O(n) |
|
|
407
|
-
| `frequency()` | 빈도 분포 | O(n) | O(n) |
|
|
408
|
-
| `summate()` | 합계 | O(n) | O(1) |
|
|
409
|
-
| `quantile(quantile)` | 사분위수 | O(n log n) | O(n) |
|
|
410
|
-
| `interquartileRange()` | 사분위수 범위 | O(n log n) | O(n) |
|
|
411
|
-
| `skewness()` | 왜도 | O(n) | O(1) |
|
|
412
|
-
| `kurtosis()` | 첨도 | O(n) | O(1) |
|
|
110
|
+
### 4. 중요: 이벤트 스트림 작업
|
|
111
|
+
이벤트 스트림(useDocument, useWindow, useHTMLElement, useWebSocket)은 본질적으로 무한합니다. 언제 이벤트 수집을 중지하고 스트림을 완료할지 정의하기 위해 sub, takeWhile 또는 limit과 같은 연산을 사용해야 합니다. 그렇지 않으면 최종 연산이 무기한 대기합니다.
|
|
413
112
|
|
|
414
113
|
```typescript
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
114
|
+
import { useDocument } from 'semantic-typescript';
|
|
115
|
+
|
|
116
|
+
// 처음 5번의 클릭만 수집
|
|
117
|
+
const first5Clicks = await useDocument('click')
|
|
118
|
+
.limit(5) // <- 필수: 스트림을 5개의 이벤트로 제한
|
|
119
|
+
.toUnordered()
|
|
120
|
+
.toArray();
|
|
121
|
+
|
|
122
|
+
// 10초 동안의 클릭 수집
|
|
123
|
+
const clicksIn10s = await useDocument('click')
|
|
124
|
+
.takeWhile((_, index, startTime = Date.now()) => Date.now() - startTime < 10000)
|
|
125
|
+
.toUnordered()
|
|
126
|
+
.toArray();
|
|
127
|
+
|
|
128
|
+
// 인덱스 2부터 5까지(0 기준)의 클릭 수집
|
|
129
|
+
const specificClicks = await useDocument('click')
|
|
130
|
+
.sub(2n, 6n) // <- 인덱스 2, 3, 4, 5의 요소를 취함
|
|
131
|
+
.toUnordered()
|
|
132
|
+
.toArray();
|
|
431
133
|
```
|
|
432
134
|
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
### 순서 보장이 필요 없는 Collector 선택(성능 우선)
|
|
436
|
-
```typescript
|
|
437
|
-
// 순서 보장이 필요 없는 경우, 최고의 성능을 위해 순서가 보장되지 않는 Collector 사용
|
|
438
|
-
let highPerformance = data
|
|
439
|
-
.filter(predicate)
|
|
440
|
-
.map(mapper)
|
|
441
|
-
.toUnoredered(); // 최고의 성능
|
|
442
|
-
```
|
|
135
|
+
**핵심 통찰**: 이벤트(예: MouseEvent)와 그 순차적 발생 인덱스(빅인트)는 `accept(event, index)` 콜백을 통해 파이프라인을 함께 전달됩니다.
|
|
443
136
|
|
|
444
|
-
###
|
|
137
|
+
### 5. 통계 활용
|
|
445
138
|
```typescript
|
|
446
|
-
|
|
447
|
-
|
|
139
|
+
const numericStream = useFrom([10, 20, 30, 40, 50]).toNumeric();
|
|
140
|
+
const average = await numericStream.average();
|
|
141
|
+
const median = await numericStream.median();
|
|
142
|
+
const standardDeviation = await numericStream.standardDeviation();
|
|
143
|
+
const skewness = await numericStream.skewness();
|
|
144
|
+
console.log(`평균: ${average}, 중앙값: ${median}, 표준편차: ${standardDeviation}`);
|
|
448
145
|
```
|
|
449
146
|
|
|
450
|
-
|
|
147
|
+
## 주요 기능
|
|
148
|
+
- **이중 스트림 유형**: 동기식 Semantic(Iterable용) 및 비동기식 Semantic(AsyncIterable 및 이벤트용) 모두에 대한 완전한 지원
|
|
149
|
+
- **풍부한 연산 집합**: filter, map, flatMap, concat, distinct, sorted, limit, skip, peek, reverse, shuffle
|
|
150
|
+
- **유연한 최종 연산**: collect(사용자 정의 컬렉터 포함), toArray, toSet, toMap, forEach, reduce, findFirst, anyMatch, allMatch, count
|
|
151
|
+
- **고급 컬렉터**: 결합(joining), 그룹화(groupingBy), 분할(partitioningBy), 합계(summation), 평균(averaging), 최대(maxBy), 최소(minBy)를 위한 내장 컬렉터
|
|
152
|
+
- **통계 모듈**: 숫자/빅인트 스트림에 대한 평균(mean), 중앙값(median), 최빈값(mode), 분산(variance), 표준 편차(standardDeviation), 범위(range), 사분위수(quantiles), 왜도(skewness), 첨도(kurtosis)를 위한 즉시 사용 가능한 메서드
|
|
153
|
+
- **유틸리티 함수**: 타입 가드(isPromise, isAsyncIterable), 비교자(useCompare), 탐색(useTraverse) 및 변환 훅
|
|
154
|
+
- **Optional<T>**: 널 가능(nullable) 값을 위한 모나딕 컨테이너, 찾기(find) 연산과 통합됨
|
|
155
|
+
|
|
156
|
+
## API 개요
|
|
157
|
+
### 핵심 클래스 및 인터페이스
|
|
158
|
+
- `Semantic<E>` / `AsynchronousSemantic<E>`: 추상적인 스트림 정의
|
|
159
|
+
- `Collectable<E>` / `AsynchronousCollectable<E>`: 최종 연산을 포함한 실행 가능한 스트림
|
|
160
|
+
- `OrderedCollectable<E>` / `UnorderedCollectable<E>`: 순서에 민감하거나 순서에 민감하지 않은 연산에 최적화된 구체화된 버전
|
|
161
|
+
- `Collector<E, A, R>`: 가변 축소(mutable reduction) 연산을 위한 추상화
|
|
162
|
+
|
|
163
|
+
### 팩토리 함수 (use*)
|
|
164
|
+
- **소스로부터**: useFrom, useRange, useFill, useEmpty
|
|
165
|
+
- **시간으로부터**: useInterval, useAnimationFrame
|
|
166
|
+
- **Web API로부터**: useBlob, useDocument, useWindow, useHTMLElement, useWebSocket
|
|
167
|
+
- **컬렉터**: useToArray, useGroupBy, useSummate, useJoin 등
|
|
168
|
+
|
|
169
|
+
## 성능 참고사항
|
|
170
|
+
- **지연 평가**: 파이프라인은 최종 연산이 호출될 때까지 실행 없이 구성됩니다.
|
|
171
|
+
- **단락 평가**: limit, anyMatch, findFirst와 같은 연산은 결과가 결정되는 즉시 요소 처리를 중지합니다.
|
|
172
|
+
- **정렬(Ordered) vs 비정렬(Unordered)**:
|
|
173
|
+
- 소스 요소의 순서가 결과에 중요하지 않은 경우(예: 합계, 최댓값 또는 toSet) 최종 연산에 `.toUnordered()`를 사용하십시오. 이는 비용이 많이 드는 정렬 단계를 건너뛰는 내부 최적화를 허용할 수 있습니다.
|
|
174
|
+
- 순서가 중요한 경우(예: 순서를 유지해야 하는 toArray) `.toOrdered()`를 사용하십시오.
|
|
175
|
+
|
|
176
|
+
## 시작하기 예제
|
|
451
177
|
```typescript
|
|
452
|
-
|
|
453
|
-
let windowed: WindowCollectable<number> = data
|
|
454
|
-
.toWindow()
|
|
455
|
-
.slide(5n, 2n); // 슬라이딩 윈도우
|
|
456
|
-
```
|
|
178
|
+
import { useFrom, useSummate, useGroupBy } from 'semantic-typescript';
|
|
457
179
|
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
180
|
+
interface Transaction {
|
|
181
|
+
id: number;
|
|
182
|
+
amount: number;
|
|
183
|
+
category: string;
|
|
184
|
+
}
|
|
463
185
|
|
|
464
|
-
|
|
465
|
-
|
|
186
|
+
const transactions: Transaction[] = [
|
|
187
|
+
{ id: 1, amount: 100, category: 'Food' },
|
|
188
|
+
{ id: 2, amount: 200, category: 'Electronics' },
|
|
189
|
+
{ id: 3, amount: 50, category: 'Food' },
|
|
190
|
+
{ id: 4, amount: 300, category: 'Electronics' },
|
|
191
|
+
];
|
|
192
|
+
|
|
193
|
+
// 카테고리별 총액 계산
|
|
194
|
+
const totalsByCategory = await useFrom(transactions)
|
|
195
|
+
.toUnordered()
|
|
196
|
+
.collect(
|
|
197
|
+
useGroupBy(
|
|
198
|
+
t => t.category,
|
|
199
|
+
t => t.amount,
|
|
200
|
+
useSummate() // 값에 대한 컬렉터
|
|
201
|
+
)
|
|
202
|
+
);
|
|
203
|
+
|
|
204
|
+
console.log(totalsByCategory); // Map { 'Food' => 150, 'Electronics' => 500 }
|
|
466
205
|
```
|
|
467
206
|
|
|
468
|
-
|
|
469
|
-
[NPMJS](https://www.npmjs.com/package/semantic-typescript)
|
|
470
|
-
|
|
471
|
-
## 중요한 참고 사항
|
|
472
|
-
|
|
473
|
-
1. **정렬 작업의 영향**: 순서가 보장되는 컬렉터에서 `sorted()` 작업은 `redirect`, `translate`, `shuffle`, `reverse`의 효과를 무시합니다.
|
|
474
|
-
2. **성능 고려 사항**: 순서 보장이 필요하지 않은 경우, `toUnordered()`를 사용하여 성능을 향상시키는 것이 좋습니다.
|
|
475
|
-
3. **메모리 사용량**: 정렬 작업에는 추가적인 O(n)의 메모리가 필요합니다.
|
|
476
|
-
4. **실시간 데이터**: 시맨틱 스트림은 실시간 데이터 처리에 적합하며 비동기 데이터 소스를 지원합니다.
|
|
207
|
+
Semantic-TypeScript는 엄격하게 설계되고 타입 안전하며 고성능의 스트림 처리 라이브러리를 추구하는 개발자를 위해 구축되었습니다. 이는 엔터프라이즈 수준의 데이터 변환 패턴의 힘을 TypeScript 생태계에 가져오며, 데이터 중심의 프론트엔드 애플리케이션, Node.js 데이터 처리 및 시퀀스를 우아하고 효율적으로 처리해야 하는 모든 시나리오에 완벽하게 적합합니다.
|
|
477
208
|
|
|
478
|
-
|
|
209
|
+
[](https://github.com/eloyhere/semantic-typescript) [](https://www.npmjs.com/package/semantic-typescript)
|