semantic-typescript 0.0.8 → 0.2.5

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