semantic-typescript 0.0.8 → 0.1.4

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.kr.md CHANGED
@@ -1,529 +1,427 @@
1
- # Semantic-TypeScript 스트림 처리 프레임워크
1
+ # Semantic-TypeScript 스트림 처리 라이브러리
2
2
 
3
3
  ## 소개
4
4
 
5
- Semantic-TypeScript는 JavaScript GeneratorFunction, Java Stream 및 MySQL Index에서 영감을 받은 현대적인 스트림 처리 라이브러리입니다. 핵심 설계 철학은 데이터 인덱싱을 통해 효율적인 데이터 처리 파이프라인을 구축하는 데 있으며, 프론트엔드 개발을 위해 타입 안전적이고 함수형 스타일의 스트리밍 작업 경험을 제공합니다.
5
+ Semantic-TypeScript는 JavaScript GeneratorFunction, Java Stream 및 MySQL Index에서 영감을 받은 현대적인 스트림 처리 라이브러리입니다. 이 라이브러리의 핵심 설계는 데이터 인덱스를 기반으로 효율적인 데이터 처리 파이프라인을 구축하여 프론트엔드 개발자에게 타입 안전성과 함수형 스타일의 스트림 조작 경험을 제공합니다.
6
6
 
7
- 기존의 동기식 처리와 달리 Semantic은 비동기 처리 모델을 채택합니다. 데이터 스트림을 생성할 최종 데이터 수신 시점은 전적으로 업스트림이 `accept` 및 `interrupt` 콜백 함수를 호출하는 시점에 따라 결정됩니다. 이 설계는 라이브러리가 실시간 데이터 스트림, 대용량 데이터 세트 및 비동기 데이터 소스를 우아하게 처리할 수 있게 합니다.
7
+ 기존의 동기식 처리와 달리 Semantic은 비동기 처리 모드를 채택합니다. 데이터 스트림을 생성할 때, 터미널이 데이터를 수신하는 시점은 업스트림이 `accept` 및 `interrupt` 콜백 함수를 언제 호출하는지에 전적으로 의존합니다. 이 설계는 라이브러리가 실시간 데이터 스트림, 대규모 데이터 세트 및 비동기 데이터 소스를 우아하게 처리할 수 있도록 합니다.
8
8
 
9
- ## 핵심 기능
9
+ ## 설치
10
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
- ### 스트림 생성 팩토리
11
+ ```bash
12
+ npm install semantic-typescript
13
+ ```
38
14
 
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)` |
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
+ | `Runnable` | 매개변수 없음, 반환값 없는 함수 |
35
+ | `Supplier<R>` | 매개변수 없이 R을 반환하는 함수 |
36
+ | `Functional<T, R>` | 단일 매개변수 변환 함수 |
37
+ | `Predicate<T>` | 단일 매개변수 조건 함수 |
38
+ | `BiFunctional<T, U, R>` | 이중 매개변수 변환 함수 |
39
+ | `BiPredicate<T, U>` | 이중 매개변수 조건 함수 |
40
+ | `Comparator<T>` | 비교 함수 |
41
+ | `TriFunctional<T, U, V, R>` | 삼중 매개변수 변환 함수 |
42
+ | `Consumer<T>` | 단일 매개변수 소비 함수 |
43
+ | `BiConsumer<T, U>` | 이중 매개변수 소비 함수 |
44
+ | `TriConsumer<T, U, V>` | 삼중 매개변수 소비 함수 |
45
+ | `Generator<T>` | 생성기 함수 |
48
46
 
49
- **코드 예시 보충:**
50
47
  ```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>();
48
+ // 타입 사용 예제
49
+ const predicate: Predicate<number> = (n) => n > 0;
50
+ const mapper: Functional<string, number> = (str) => str.length;
51
+ const comparator: Comparator<number> = (a, b) => a - b;
64
52
  ```
65
53
 
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)` 난수 |
54
+ ## 타입 가드
55
+
56
+ | 함수 | 설명 | 시간 복잡도 | 공간 복잡도 |
57
+ |------|------|------------|------------|
58
+ | `validate<T>(t: MaybeInvalid<T>): t is T` | 값이 null 또는 undefined가 아님을 검증 | O(1) | O(1) |
59
+ | `invalidate<T>(t: MaybeInvalid<T>): t is null \| undefined` | 값이 null 또는 undefined임을 검증 | O(1) | O(1) |
60
+ | `isBoolean(t: unknown): t is boolean` | 불리언 여부 확인 | O(1) | O(1) |
61
+ | `isString(t: unknown): t is string` | 문자열 여부 확인 | O(1) | O(1) |
62
+ | `isNumber(t: unknown): t is number` | 숫자 여부 확인 | O(1) | O(1) |
63
+ | `isFunction(t: unknown): t is Function` | 함수 여부 확인 | O(1) | O(1) |
64
+ | `isObject(t: unknown): t is object` | 객체 여부 확인 | O(1) | O(1) |
65
+ | `isSymbol(t: unknown): t is symbol` | 심볼 여부 확인 | O(1) | O(1) |
66
+ | `isBigint(t: unknown): t is bigint` | BigInt 여부 확인 | O(1) | O(1) |
67
+ | `isPrimitive(t: unknown): t is Primitive` | 기본 타입 여부 확인 | O(1) | O(1) |
68
+ | `isIterable(t: unknown): t is Iterable<unknown>` | 반복 가능 여부 확인 | O(1) | O(1) |
69
+ | `isOptional(t: unknown): t is Optional<unknown>` | Optional 인스턴스 여부 확인 | O(1) | O(1) |
70
+ | `isSemantic(t: unknown): t is Semantic<unknown>` | Semantic 인스턴스 여부 확인 | O(1) | O(1) |
71
+ | `isCollector(t: unknown): t is Collector<unknown, unknown, unknown>` | Collector 인스턴스 여부 확인 | O(1) | O(1) |
72
+ | `isCollectable(t: unknown): t is Collectable<unknown>` | Collectable 인스턴스 여부 확인 | O(1) | O(1) |
73
+ | `isOrderedCollectable(t: unknown): t is OrderedCollectable<unknown>` | OrderedCollectable 인스턴스 여부 확인 | O(1) | O(1) |
74
+ | `isWindowCollectable(t: unknown): t is WindowCollectable<unknown>` | WindowCollectable 인스턴스 여부 확인 | O(1) | O(1) |
75
+ | `isUnorderedCollectable(t: unknown): t is UnorderedCollectable<unknown>` | UnorderedCollectable 인스턴스 여부 확인 | O(1) | O(1) |
76
+ | `isStatistics(t: unknown): t is Statistics<unknown, number \| bigint>` | Statistics 인스턴스 여부 확인 | O(1) | O(1) |
77
+ | `isNumericStatistics(t: unknown): t is NumericStatistics<unknown>` | NumericStatistics 인스턴스 여부 확인 | O(1) | O(1) |
78
+ | `isBigIntStatistics(t: unknown): t is BigIntStatistics<unknown>` | BigIntStatistics 인스턴스 여부 확인 | O(1) | O(1) |
74
79
 
75
- **코드 예시 보충:**
76
80
  ```typescript
77
- import { validate, invalidate, useCompare, useRandom } from 'semantic-typescript';
81
+ // 타입 가드 사용 예제
82
+ const value: unknown = "hello";
78
83
 
79
- // 데이터 유효성 검증
80
- const data: string | null = "hello";
81
- if (validate(data)) {
82
- console.log(data.toUpperCase()); // validate가 데이터가 null이 아님을 보장하므로 안전한 호출
84
+ if (isString(value)) {
85
+ console.log(value.length); // 타입 안전, value는 string으로 추론
83
86
  }
84
87
 
85
- const nullData: string | null = null;
86
- if (invalidate(nullData)) {
87
- console.log("데이터 무효"); // invalidate가 null을 감지했으므로 실행됨
88
+ if (isOptional(someValue)) {
89
+ someValue.ifPresent(val => console.log(val));
88
90
  }
89
-
90
- // 값 비교
91
- const comparison = useCompare("apple", "banana"); // -1
92
-
93
- // 난수 생성
94
- const randomNum = useRandom(42); // 시드 42 기반 난수
95
91
  ```
96
92
 
97
- ## 핵심 클래스 상세
98
-
99
- ### Optional<T> - 안전한 Null 값 처리
100
-
101
- Optional 클래스는 null 또는 undefined일 수 있는 값을 안전하게 처리하기 위한 함수형 접근 방식을 제공합니다.
93
+ ## 유틸리티 함수
102
94
 
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>` | non-null Optional 생성 | O(1) |
95
+ | 함수 | 설명 | 시간 복잡도 | 공간 복잡도 |
96
+ |------|------|------------|------------|
97
+ | `useCompare<T>(t1: T, t2: T): number` | 범용 비교 함수 | O(1) | O(1) |
98
+ | `useRandom<T = number \| bigint>(index: T): T` | 의사 난수 생성기 | O(log n) | O(1) |
115
99
 
116
- **코드 예시 보충:**
117
100
  ```typescript
118
- import { Optional } from 'semantic-typescript';
101
+ // 유틸리티 함수 사용 예제
102
+ const numbers = [3, 1, 4, 1, 5];
103
+ numbers.sort(useCompare); // [1, 1, 3, 4, 5]
119
104
 
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
- }
105
+ const randomNum = useRandom(42); // 시드 기반 난수
106
+ const randomBigInt = useRandom(1000n); // BigInt 난수
142
107
  ```
143
108
 
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(`인덱스 ${index}의 요소 ${val}`)); // 요소 확인
185
-
186
- // 참고: 스트림은 아직 실행되지 않음, 터미널 연산을 위해 Collectable로 변환 필요
187
- ```
109
+ ## 팩토리 메서드
188
110
 
189
- #### 스트림 터미널 연산
111
+ ### Optional 팩토리 메서드
190
112
 
191
- | 메서드 | 반환 타입 | 설명 | 성능 특성 |
192
- |------|----------|------|----------|
193
- | `toOrdered()` | `OrderedCollectable<E>` | 정렬된 컬렉션으로 변환 | 정렬 연산, 낮은 성능 |
194
- | `toUnordered()` | `UnorderedCollectable<E>` | 비정렬 컬렉션으로 변환 | 가장 빠름, 정렬 없음 |
195
- | `toWindow()` | `WindowCollectable<E>` | 윈도우 컬렉션으로 변환 | 정렬 연산, 낮은 성능 |
196
- | `toNumericStatistics()` | `Statistics<E, number>` | 숫자 통계 분석 | 정렬 연산, 낮은 성능 |
197
- | `toBigintStatistics()` | `Statistics<E, bigint>` | Big integer 통계 분석 | 정렬 연산, 낮은 성능 |
198
- | `sorted()` | `OrderedCollectable<E>` | 자연 정렬 | 재지정 결과 재정의 |
199
- | `sorted(comparator)` | `OrderedCollectable<E>` | 사용자 정의 정렬 | 재지정 결과 재정의 |
113
+ | 메서드 | 설명 | 시간 복잡도 | 공간 복잡도 |
114
+ |--------|------|------------|------------|
115
+ | `Optional.empty<T>()` | Optional 생성 | O(1) | O(1) |
116
+ | `Optional.of<T>(value)` | 값을 가진 Optional 생성 | O(1) | O(1) |
117
+ | `Optional.ofNullable<T>(value)` | null 허용 Optional 생성 | O(1) | O(1) |
118
+ | `Optional.ofNonNull<T>(value)` | null이 아닌 Optional 생성 | O(1) | O(1) |
200
119
 
201
- **코드 예시 보충:**
202
120
  ```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을 얻은 후 터미널 메서드 사용 필요
121
+ // Optional 사용 예제
122
+ const emptyOpt = Optional.empty<number>();
123
+ const presentOpt = Optional.of(42);
124
+ const nullableOpt = Optional.ofNullable<string>(null);
125
+ const nonNullOpt = Optional.ofNonNull("hello");
126
+
127
+ presentOpt.ifPresent(val => console.log(val)); // 42 출력
128
+ console.log(emptyOpt.orElse(100)); // 100 출력
223
129
  ```
224
130
 
225
- ### Collector<E, A, R> - 데이터 수집기
226
-
227
- 수집기는 스트림 데이터를 특정 구조로 집계하는 데 사용됩니다.
131
+ ### Collector 팩토리 메서드
228
132
 
229
- | 메서드 | 설명 | 사용 시나리오 |
230
- |------|------|----------|
231
- | `collect(generator)` | 데이터 수집 실행 | 스트림 터미널 연산 |
232
- | `static full(identity, accumulator, finisher)` | 완전한 수집기 생성 | 완전한 처리 필요 |
233
- | `static shortable(identity, interruptor, accumulator, finisher)` | 중단 가능 수집기 생성 | 조기 종료 가능 |
133
+ | 메서드 | 설명 | 시간 복잡도 | 공간 복잡도 |
134
+ |--------|------|------------|------------|
135
+ | `Collector.full(identity, accumulator, finisher)` | 완전한 수집기 생성 | O(1) | O(1) |
136
+ | `Collector.shortable(identity, interruptor, accumulator, finisher)` | 중단 가능한 수집기 생성 | O(1) | O(1) |
234
137
 
235
- **코드 예시 보충:**
236
138
  ```typescript
237
- import { Collector } from 'semantic-typescript';
238
-
239
- // 사용자 정의 수집기 생성
139
+ // Collector 사용 예제
240
140
  const sumCollector = Collector.full(
241
- () => 0, // 초기 값
242
- (acc, value) => acc + value, // 누산기
243
- result => result // 완료 함수
141
+ () => 0,
142
+ (sum, num) => sum + num,
143
+ result => result
244
144
  );
245
145
 
246
- // 수집기 사용 (Semantic에서 Collectable로 변환 필요)
247
146
  const numbers = from([1, 2, 3, 4, 5]);
248
- const sum = numbers.toUnordered().collect(sumCollector); // 15
147
+ const total = numbers.toUnoredered().collect(sumCollector); // 15
249
148
  ```
250
149
 
251
- ### Collectable<E> - 수집 가능 데이터 추상 클래스
252
-
253
- 풍부한 데이터 집계 및 변환 메서드를 제공합니다. **참고: 반드시 Semantic 인스턴스를 통해 sorted(), toOrdered() 등을 먼저 호출하여 Collectable 인스턴스를 얻은 후 다음 메서드들을 사용해야 합니다.**
150
+ ### Semantic 팩토리 메서드
254
151
 
255
- #### 데이터 쿼리 연산
152
+ | 메서드 | 설명 | 시간 복잡도 | 공간 복잡도 |
153
+ |-------|------|-------------|-------------|
154
+ | `blob(blob, chunkSize)` | Blob으로부터 스트림 생성 | O(n) | O(chunkSize) |
155
+ | `empty<E>()` | 빈 스트림 생성 | O(1) | O(1) |
156
+ | `fill<E>(element, count)` | 채워진 스트림 생성 | O(n) | O(1) |
157
+ | `from<E>(iterable)` | 반복 가능 객체로부터 스트림 생성 | O(1) | O(1) |
158
+ | `interval(period, delay?)` | 정기적 간격 스트림 생성 | O(1)* | O(1) |
159
+ | `iterate<E>(generator)` | 생성기로부터 스트림 생성 | O(1) | O(1) |
160
+ | `range(start, end, step)` | 숫자 범위 스트림 생성 | O(n) | O(1) |
161
+ | `websocket(websocket)` | WebSocket으로부터 스트림 생성 | O(1) | O(1) |
256
162
 
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
163
  ```typescript
269
- import { from } from 'semantic-typescript';
270
-
271
- const numbers = from([1, 2, 3, 4, 5]);
164
+ // Semantic 팩토리 메서드 사용 예시
272
165
 
273
- // 터미널 메서드 사용 반드시 Collectable로 변환
274
- const collectable = numbers.toUnordered();
166
+ // Blob으로부터 스트림 생성 (청크 읽기)
167
+ blob(someBlob, 1024n)
168
+ .toUnordered()
169
+ .write(WritableStream)
170
+ .then(callback) // 스트림 쓰기 성공
171
+ .catch(writeFi); // 스트림 쓰기 실패
275
172
 
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
- ```
173
+ // 다른 스트림과 연결될 때까지 실행되지 않는 빈 스트림 생성
174
+ empty<string>()
175
+ .toUnordered()
176
+ .join(); //[]
284
177
 
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';
178
+ // 채워진 스트림 생성
179
+ const filledStream = fill("hello", 3); // "hello", "hello", "hello"
304
180
 
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
- ]);
181
+ // 초기 지연 2초, 실행 주기 5초의 시계열 스트림 생성
182
+ // 타이머 메커니즘으로 구현, 시스템 스케줄링 제한으로 인한 시간 변동 가능성 있음
183
+ const intervalStream = interval(5000, 2000);
310
184
 
311
- // 집계 연산 사용 반드시 Collectable로 변환
312
- const collectable = people.toUnordered();
185
+ // 반복 가능 객체로부터 스트림 생성
186
+ const numberStream = from([1, 2, 3, 4, 5]);
187
+ const stringStream = from(new Set(["Alex", "Bob"]));
313
188
 
314
- // 그룹화 연산
315
- const byCity = collectable.group(person => person.city);
316
- // Map { "New York" => [{name: "Alice", ...}, {name: "Charlie", ...}], "London" => [{name: "Bob", ...}] }
189
+ // 범위 스트림 생성
190
+ const rangeStream = range(1, 10, 2); // 1, 3, 5, 7, 9
317
191
 
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, ...})
192
+ // WebSocket 이벤트 스트림
193
+ const ws = new WebSocket("ws://localhost:8080");
194
+ websocket(ws)
195
+ .filter((event)=> event.type === "message") // 메시지 이벤트만 모니터링
196
+ .toUnordered() // 이벤트는 일반적으로 정렬되지 않음
197
+ .forEach((event)=> receive(event)); // 메시지 수신
335
198
  ```
336
199
 
337
- ### 특정 수집기 구현
200
+ ## Semantic 클래스 메서드
201
+
202
+ | 메서드 | 설명 | 시간 복잡도 | 공간 복잡도 |
203
+ |--------|------|------------|------------|
204
+ | `concat(other)` | 두 스트림 연결 | O(n) | O(1) |
205
+ | `distinct()` | 중복 제거 | O(n) | O(n) |
206
+ | `distinct(comparator)` | 비교기를 사용한 중복 제거 | O(n²) | O(n) |
207
+ | `dropWhile(predicate)` | 조건을 만족하는 요소 버리기 | O(n) | O(1) |
208
+ | `filter(predicate)` | 요소 필터링 | O(n) | O(1) |
209
+ | `flat(mapper)` | 평면화 매핑 | O(n × m) | O(1) |
210
+ | `flatMap(mapper)` | 새로운 타입으로 평면화 매핑 | O(n × m) | O(1) |
211
+ | `limit(n)` | 요소 수 제한 | O(n) | O(1) |
212
+ | `map(mapper)` | 매핑 변환 | O(n) | O(1) |
213
+ | `peek(consumer)` | 요소 검사 | O(n) | O(1) |
214
+ | `redirect(redirector)` | 인덱스 리디렉션 | O(n) | O(1) |
215
+ | `reverse()` | 스트림 반전 | O(n) | O(1) |
216
+ | `shuffle()` | 무작위 셔플 | O(n) | O(1) |
217
+ | `shuffle(mapper)` | 매퍼를 사용한 셔플 | O(n) | O(1) |
218
+ | `skip(n)` | 처음 n개 요소 건너뛰기 | O(n) | O(1) |
219
+ | `sorted()` | 정렬 | O(n log n) | O(n) |
220
+ | `sorted(comparator)` | 비교기를 사용한 정렬 | O(n log n) | O(n) |
221
+ | `sub(start, end)` | 서브 스트림 가져오기 | O(n) | O(1) |
222
+ | `takeWhile(predicate)` | 조건을 만족하는 요소 가져오기 | O(n) | O(1) |
223
+ | `translate(offset)` | 인덱스 변환 | O(n) | O(1) |
224
+ | `translate(translator)` | 변환기를 사용한 인덱스 변환 | O(n) | O(1) |
338
225
 
339
- #### UnorderedCollectable<E>
340
- - **특징**: 가장 빠른 수집기, 정렬 없음
341
- - **사용 시나리오**: 순서 중요하지 않음, 최대 성능 원할
342
- - **메서드**: 모든 Collectable 메서드 상속
226
+ ```typescript
227
+ // Semantic 작업 예제
228
+ const result = from([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
229
+ .filter(n => n % 2 === 0) // 짝수 필터링
230
+ .map(n => n * 2) // 2배 변환
231
+ .skip(1) // 첫 번째 요소 건너뛰기
232
+ .limit(3) // 3개 요소로 제한
233
+ .toArray(); // 배열로 변환
234
+ // 결과: [8, 12, 20]
235
+
236
+ // 복잡한 작업 예제
237
+ const complexResult = range(1, 100, 1)
238
+ .flatMap(n => from([n, n * 2])) // 각 요소를 2개 요소로 매핑
239
+ .distinct() // 중복 제거
240
+ .shuffle() // 무작위 셔플
241
+ .takeWhile(n => n < 50) // 50 미만 요소 가져오기
242
+ .toOrdered() // 정렬된 수집기로 변환
243
+ .toArray(); // 배열로 변환
244
+ ```
343
245
 
344
- #### OrderedCollectable<E>
345
- - **특징**: 요소 순서 보장, 낮은 성능
346
- - **사용 시나리오**: 정렬된 결과 필요
347
- - **특별 메서드**: 모든 메서드 상속, 내부 정렬 상태 유지
246
+ ## 수집기 변환 메서드
348
247
 
349
- #### WindowCollectable<E>
350
- - **특징**: 슬라이딩 윈도우 연산 지원
351
- - **사용 시나리오**: 시계열 데이터 분석
352
- - **특별 메서드**:
353
- - `slide(size, step)` - 슬라이딩 윈도우
354
- - `tumble(size)` - 텀블링 윈도우
248
+ | 메서드 | 설명 | 시간 복잡도 | 공간 복잡도 |
249
+ |--------|------|------------|------------|
250
+ | `toUnoredered()` | 비정렬 수집기로 변환 (성능 우선) | O(1) | O(1) |
251
+ | `toOrdered()` | 정렬된 수집기로 변환 | O(1) | O(1) |
252
+ | `sorted()` | 정렬 후 정렬된 수집기로 변환 | O(n log n) | O(n) |
253
+ | `toWindow()` | 윈도우 수집기로 변환 | O(1) | O(1) |
254
+ | `toNumericStatistics()` | 숫자 통계로 변환 | O(1) | O(1) |
255
+ | `toBigintStatistics()` | BigInt 통계로 변환 | O(1) | O(1) |
355
256
 
356
- **코드 예시 보충:**
357
257
  ```typescript
358
- import { from } from 'semantic-typescript';
359
-
360
- const data = from([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
258
+ // 수집기 변환 예제
259
+ const numbers = from([3, 1, 4, 1, 5, 9, 2, 6, 5]);
260
+
261
+ // 성능 우선: 비정렬 수집기 사용
262
+ const unordered = numbers
263
+ .filter(n => n > 3)
264
+ .toUnoredered();
265
+
266
+ // 정렬 필요: 정렬된 수집기 사용
267
+ const ordered = numbers
268
+ .sorted()
269
+ .toOrdered();
270
+
271
+ // 통계 분석: 통계 수집기 사용
272
+ const stats = numbers
273
+ .toNumericStatistics();
274
+
275
+ console.log(stats.mean()); // 평균값
276
+ console.log(stats.median()); // 중앙값
277
+ console.log(stats.standardDeviation()); // 표준편차
278
+
279
+ // 윈도우 작업
280
+ const windowed = numbers
281
+ .toWindow()
282
+ .tumble(3n); // 3개 요소 윈도우
283
+
284
+ windowed.forEach(window => {
285
+ console.log(window.toArray()); // 각 윈도우 내용
286
+ });
287
+ ```
361
288
 
362
- // 비정렬 수집기 (가장 빠름)
363
- const unordered = data.toUnordered();
364
- const unorderedArray = unordered.toArray(); // 원본 순서 유지 가능 [1, 2, 3, ...]
289
+ ## Collectable 수집 메서드
290
+
291
+ | 메서드 | 설명 | 시간 복잡도 | 공간 복잡도 |
292
+ |--------|------|------------|------------|
293
+ | `anyMatch(predicate)` | 일치하는 요소 존재 여부 확인 | O(n) | O(1) |
294
+ | `allMatch(predicate)` | 모든 요소 일치 여부 확인 | O(n) | O(1) |
295
+ | `count()` | 요소 개수 세기 | O(n) | O(1) |
296
+ | `isEmpty()` | 비어 있는지 확인 | O(1) | O(1) |
297
+ | `findAny()` | 아무 요소 찾기 | O(n) | O(1) |
298
+ | `findFirst()` | 첫 번째 요소 찾기 | O(n) | O(1) |
299
+ | `findLast()` | 마지막 요소 찾기 | O(n) | O(1) |
300
+ | `forEach(action)` | 모든 요소 반복 | O(n) | O(1) |
301
+ | `group(classifier)` | 분류기로 그룹화 | O(n) | O(n) |
302
+ | `groupBy(keyExtractor, valueExtractor)` | 키-값 추출기로 그룹화 | O(n) | O(n) |
303
+ | `join()` | 문자열로 결합 | O(n) | O(n) |
304
+ | `join(delimiter)` | 구분자로 결합 | O(n) | O(n) |
305
+ | `nonMatch(predicate)` | 일치하는 요소 없음 확인 | O(n) | O(1) |
306
+ | `partition(count)` | 개수로 분할 | O(n) | O(n) |
307
+ | `partitionBy(classifier)` | 분류기로 분할 | O(n) | O(n) |
308
+ | `reduce(accumulator)` | 축소 작업 | O(n) | O(1) |
309
+ | `reduce(identity, accumulator)` | 초기값을 사용한 축소 | O(n) | O(1) |
310
+ | `toArray()` | 배열로 변환 | O(n) | O(n) |
311
+ | `toMap(keyExtractor, valueExtractor)` | Map으로 변환 | O(n) | O(n) |
312
+ | `toSet()` | Set으로 변환 | O(n) | O(n) |
313
+ | `write(stream)` | 스트림에 쓰기 | O(n) | O(1) |
365
314
 
366
- // 정렬 수집기
367
- const ordered = data.toOrdered();
368
- const orderedArray = ordered.toArray(); // 정렬 보장 [1, 2, 3, ...]
315
+ ```typescript
316
+ // Collectable 작업 예제
317
+ const data = from([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
318
+ .filter(n => n % 2 === 0)
319
+ .toOrdered();
320
+
321
+ // 일치 확인
322
+ console.log(data.anyMatch(n => n > 5)); // true
323
+ console.log(data.allMatch(n => n < 20)); // true
324
+
325
+ // 검색 작업
326
+ data.findFirst().ifPresent(n => console.log(n)); // 2
327
+ data.findAny().ifPresent(n => console.log(n)); // 아무 요소
328
+
329
+ // 그룹화 작업
330
+ const grouped = data.groupBy(
331
+ n => n > 5 ? "large" : "small",
332
+ n => n * 2
333
+ );
334
+ // {small: [4, 8], large: [12, 16, 20]}
369
335
 
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], ...
336
+ // 축소 작업
337
+ const sum = data.reduce(0, (acc, n) => acc + n); // 30
374
338
 
375
- const tumblingWindows = windowed.tumble(4n); // 텀블링 윈도우 크기 4
376
- // 윈도우 1: [1, 2, 3, 4], 윈도우 2: [5, 6, 7, 8], ...
339
+ // 출력 작업
340
+ data.join(", "); // "2, 4, 6, 8, 10"
377
341
  ```
378
342
 
379
- ### Statistics<E, D> - 통계 분석
380
-
381
- 통계 분석 기본 클래스로 풍부한 통계 계산 메서드를 제공합니다. **참고: 반드시 Semantic 인스턴스를 통해 toNumericStatistics() 또는 toBigIntStatistics()를 호출하여 Statistics 인스턴스를 얻은 후 다음 메서드들을 사용해야 합니다.**
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
- **코드 예시 보충:**
343
+ ## 통계 분석 메서드
344
+
345
+ ### NumericStatistics 메서드
346
+
347
+ | 메서드 | 설명 | 시간 복잡도 | 공간 복잡도 |
348
+ |--------|------|------------|------------|
349
+ | `range()` | 범위 | O(n) | O(1) |
350
+ | `variance()` | 분산 | O(n) | O(1) |
351
+ | `standardDeviation()` | 표준편차 | O(n) | O(1) |
352
+ | `mean()` | 평균 | O(n) | O(1) |
353
+ | `median()` | 중앙값 | O(n log n) | O(n) |
354
+ | `mode()` | 최빈값 | O(n) | O(n) |
355
+ | `frequency()` | 빈도 분포 | O(n) | O(n) |
356
+ | `summate()` | 합계 | O(n) | O(1) |
357
+ | `quantile(quantile)` | 분위수 | O(n log n) | O(n) |
358
+ | `interquartileRange()` | 사분위 범위 | O(n log n) | O(n) |
359
+ | `skewness()` | 왜도 | O(n) | O(1) |
360
+ | `kurtosis()` | 첨도 | O(n) | O(1) |
361
+
403
362
  ```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, ...}
363
+ // 통계 분석 예제
364
+ const numbers = from([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
365
+ .toNumericStatistics();
366
+
367
+ console.log("평균:", numbers.mean()); // 5.5
368
+ console.log("중앙값:", numbers.median()); // 5.5
369
+ console.log("표준편차:", numbers.standardDeviation()); // ~2.87
370
+ console.log("합계:", numbers.summate()); // 55
371
+
372
+ // 매퍼를 사용한 통계 분석
373
+ const objects = from([
374
+ { value: 10 },
375
+ { value: 20 },
376
+ { value: 30 }
377
+ ]).toNumericStatistics();
378
+
379
+ console.log("매핑된 평균:", objects.mean(obj => obj.value)); // 20
430
380
  ```
431
381
 
432
- #### 특정 통계 구현 클래스
433
-
434
- **NumericStatistics<E>**
435
- - number 타입 통계 분석 처리
436
- - 모든 통계 계산이 number 타입 반환
437
-
438
- **BigIntStatistics<E>**
439
- - bigint 타입 통계 분석 처리
440
- - 모든 통계 계산이 bigint 타입 반환
382
+ ## 성능 선택 가이드
441
383
 
442
- **코드 예시 보충:**
384
+ ### 비정렬 수집기 선택 (성능 우선)
443
385
  ```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
386
+ // 순서 보장이 필요하지 않은 경우
387
+ const highPerformance = data
388
+ .filter(predicate)
389
+ .map(mapper)
390
+ .toUnoredered(); // 최고 성능
391
+ ```
452
392
 
453
- // Big integer 통계
454
- const bigintData = from([100n, 200n, 300n, 400n, 500n]);
455
- const bigintStats = bigintData.toBigIntStatistics();
393
+ ### 정렬된 수집기 선택 (순서 필요)
394
+ ```typescript
395
+ // 요소 순서를 유지해야 하는 경우
396
+ const ordered = data.sorted(comparator);
397
+ ```
456
398
 
457
- console.log(bigintStats.mean()); // 300n
458
- console.log(bigintStats.summate()); // 1500n
399
+ ### 윈도우 수집기 선택 (윈도우 작업)
400
+ ```typescript
401
+ // 윈도우 작업이 필요한 경우
402
+ const windowed = data
403
+ .toWindow()
404
+ .slide(5n, 2n); // 슬라이딩 윈도우
405
+ ```
459
406
 
460
- // 매퍼 함수를 사용한 통계
461
- const objectData = from([
462
- { value: 15 },
463
- { value: 25 },
464
- { value: 35 },
465
- { value: 45 }
466
- ]);
407
+ ### 통계 분석 선택 (숫자 계산)
408
+ ```typescript
409
+ // 통계 분석이 필요한 경우
410
+ const stats = data
411
+ .toNumericStatistics(); // 숫자 통계
467
412
 
468
- const objectStats = objectData.toNumericStatistics();
469
- const meanWithMapper = objectStats.mean(obj => obj.value); // 30
470
- const sumWithMapper = objectStats.summate(obj => obj.value); // 120
413
+ const bigIntStats = data
414
+ .toBigintStatistics(); // BigInt 통계
471
415
  ```
472
416
 
473
- ## 완전한 사용 예시
417
+ [GitHub](https://github.com/eloyhere/semantic-typescript)
418
+ [NPMJS](https://www.npmjs.com/package/semantic-typescript)
474
419
 
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
- }
420
+ ## 중요한 주의사항
504
421
 
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
- ```
422
+ 1. **정렬 작업의 영향**: 정렬된 수집기에서 `sorted()` 작업은 `redirect`, `translate`, `shuffle`, `reverse` 효과를 덮어씁니다
423
+ 2. **성능 고려사항**: 순서 보장이 필요하지 않으면 `toUnoredered()`를 우선하여 나은 성능을 얻으세요
424
+ 3. **메모리 사용량**: 정렬 작업에는 O(n)의 추가 공간이 필요합니다
425
+ 4. **실시간 데이터**: Semantic 스트림은 실시간 데이터에 적합하며 비동기 데이터 소스를 지원합니다
513
426
 
514
- ## 중요한 사용 규칙 요약
515
-
516
- 1. **스트림 생성**: `from()`, `range()`, `fill()` 등 팩토리 메서드를 사용하여 Semantic 인스턴스 생성
517
- 2. **스트림 변환**: Semantic 인스턴스에서 `map()`, `filter()`, `distinct()` 등 메서드 호출
518
- 3. **Collectable로 변환**: 반드시 Semantic 인스턴스를 통해 다음 메서드 중 하나 호출:
519
- - `toOrdered()` - 정렬 수집기
520
- - `toUnordered()` - 비정렬 수집기 (가장 빠름)
521
- - `toWindow()` - 윈도우 수집기
522
- - `toNumericStatistics()` - 숫자 통계
523
- - `toBigIntStatistics()` - Big integer 통계
524
- - `sorted()` - 자연 정렬
525
- - `sorted(comparator)` - 사용자 정의 정렬
526
- 4. **터미널 연산**: Collectable 인스턴스에서 `toArray()`, `count()`, `summate()` 등 터미널 메서드 호출
527
- 5. **데이터 검증**: `validate()`를 사용하여 데이터가 null/undefined가 아님을 보장, `invalidate()`를 사용하여 무효한 데이터 확인
528
-
529
- 이 설계는 타입 안전성과 성능 최적화를 보장하면서 풍부한 스트림 처리 기능을 제공합니다.
427
+ 라이브러리는 TypeScript 개발자에게 강력하고 유연한 스트림 처리 기능을 제공하며 함수형 프로그래밍의 이점과 타입 안전성을 결합합니다.