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/dist/collectable.d.ts +84 -0
- package/dist/collectable.js +476 -0
- package/dist/collector.d.ts +24 -0
- package/dist/collector.js +63 -0
- package/dist/factory.d.ts +11 -0
- package/dist/factory.js +248 -0
- package/dist/guard.d.ts +23 -0
- package/dist/guard.js +85 -0
- package/dist/hook.d.ts +2 -0
- package/dist/hook.js +64 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.js +9 -0
- package/dist/optional.d.ts +18 -0
- package/dist/optional.js +65 -0
- package/dist/semantic.d.ts +9 -272
- package/dist/semantic.js +38 -1679
- package/dist/statistics.d.ts +101 -0
- package/dist/statistics.js +765 -0
- package/dist/symbol.d.ts +10 -0
- package/dist/symbol.js +10 -0
- package/dist/utility.d.ts +49 -0
- package/dist/utility.js +17 -0
- package/package.json +54 -8
- package/readme.cn.md +387 -445
- package/readme.de.md +393 -448
- package/readme.es.md +392 -446
- package/readme.fr.md +396 -450
- package/readme.jp.md +390 -447
- package/readme.kr.md +396 -453
- package/readme.md +389 -445
- package/readme.ru.md +391 -447
- package/readme.tw.md +403 -444
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은 비동기 처리
|
|
7
|
+
기존의 동기식 처리와 달리 Semantic은 비동기 처리 모드를 채택합니다. 데이터 스트림을 생성할 때, 터미널이 데이터를 수신하는 시점은 업스트림이 `accept` 및 `interrupt` 콜백 함수를 언제 호출하는지에 전적으로 의존합니다. 이 설계는 라이브러리가 실시간 데이터 스트림, 대규모 데이터 세트 및 비동기 데이터 소스를 우아하게 처리할 수 있도록 합니다.
|
|
8
8
|
|
|
9
|
-
##
|
|
9
|
+
## 설치
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
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
|
-
|
|
|
42
|
-
|
|
43
|
-
| `
|
|
44
|
-
| `
|
|
45
|
-
| `
|
|
46
|
-
| `
|
|
47
|
-
| `
|
|
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
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
const
|
|
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
|
-
|
|
87
|
+
// 타입 가드 사용 예제
|
|
88
|
+
const value: unknown = "hello";
|
|
78
89
|
|
|
79
|
-
|
|
80
|
-
|
|
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
|
-
|
|
86
|
-
|
|
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
|
-
|
|
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
|
-
|
|
119
|
-
|
|
120
|
-
//
|
|
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
|
|
125
|
-
|
|
126
|
-
.map(val => val.toUpperCase()) // 대문자로 변환
|
|
127
|
-
.getOrDefault("default"); // 값 또는 기본값 가져오기
|
|
111
|
+
const randomNum = useRandom(42); // 시드 기반 난수
|
|
112
|
+
const randomBigInt = useRandom(1000n); // BigInt 난수
|
|
113
|
+
```
|
|
128
114
|
|
|
129
|
-
|
|
115
|
+
## 팩토리 메서드
|
|
130
116
|
|
|
131
|
-
|
|
132
|
-
optionalValue.ifPresent(val => {
|
|
133
|
-
console.log(`값 존재: ${val}`);
|
|
134
|
-
});
|
|
117
|
+
### Optional 팩토리 메서드
|
|
135
118
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
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
|
-
|
|
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
|
-
|
|
137
|
+
### Collector 팩토리 메서드
|
|
177
138
|
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
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
|
-
|
|
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
|
-
| `
|
|
194
|
-
| `
|
|
195
|
-
| `
|
|
196
|
-
| `
|
|
197
|
-
| `
|
|
198
|
-
| `
|
|
199
|
-
| `
|
|
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
|
-
|
|
190
|
+
// Semantic 팩토리 메서드 사용 예시
|
|
204
191
|
|
|
205
|
-
|
|
192
|
+
// Blob으로부터 스트림 생성 (청크 읽기)
|
|
193
|
+
blob(someBlob, 1024n)
|
|
194
|
+
.toUnordered()
|
|
195
|
+
.write(WritableStream)
|
|
196
|
+
.then(callback) // 스트림 쓰기 성공
|
|
197
|
+
.catch(writeFi); // 스트림 쓰기 실패
|
|
206
198
|
|
|
207
|
-
//
|
|
208
|
-
|
|
199
|
+
// 다른 스트림과 연결될 때까지 실행되지 않는 빈 스트림 생성
|
|
200
|
+
empty<string>()
|
|
201
|
+
.toUnordered()
|
|
202
|
+
.join(); //[]
|
|
209
203
|
|
|
210
|
-
//
|
|
211
|
-
const
|
|
204
|
+
// 채워진 스트림 생성
|
|
205
|
+
const filledStream = fill("hello", 3); // "hello", "hello", "hello"
|
|
212
206
|
|
|
213
|
-
//
|
|
214
|
-
|
|
207
|
+
// 초기 지연 2초, 실행 주기 5초의 시계열 스트림 생성
|
|
208
|
+
// 타이머 메커니즘으로 구현, 시스템 스케줄링 제한으로 인한 시간 변동 가능성 있음
|
|
209
|
+
const intervalStream = interval(5000, 2000);
|
|
215
210
|
|
|
216
|
-
//
|
|
217
|
-
const
|
|
211
|
+
// 반복 가능 객체로부터 스트림 생성
|
|
212
|
+
const numberStream = from([1, 2, 3, 4, 5]);
|
|
213
|
+
const stringStream = from(new Set(["Alex", "Bob"]));
|
|
218
214
|
|
|
219
|
-
//
|
|
220
|
-
const
|
|
215
|
+
// 범위 스트림 생성
|
|
216
|
+
const rangeStream = range(1, 10, 2); // 1, 3, 5, 7, 9
|
|
221
217
|
|
|
222
|
-
//
|
|
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
|
-
|
|
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
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
()
|
|
242
|
-
(
|
|
243
|
-
|
|
244
|
-
);
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
const
|
|
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
|
-
|
|
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
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
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
|
-
| `
|
|
290
|
-
| `
|
|
291
|
-
| `
|
|
292
|
-
| `
|
|
293
|
-
| `
|
|
294
|
-
| `
|
|
295
|
-
| `
|
|
296
|
-
| `
|
|
297
|
-
| `
|
|
298
|
-
| `
|
|
299
|
-
| `
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
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
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
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
|
-
//
|
|
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
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
- **메서드**: 모든 Collectable 메서드 상속
|
|
343
|
-
|
|
344
|
-
#### OrderedCollectable<E>
|
|
345
|
-
- **특징**: 요소 순서 보장, 낮은 성능
|
|
346
|
-
- **사용 시나리오**: 정렬된 결과 필요
|
|
347
|
-
- **특별 메서드**: 모든 메서드 상속, 내부 정렬 상태 유지
|
|
384
|
+
// 출력 작업
|
|
385
|
+
data.join(", "); // "2, 4, 6, 8, 10"
|
|
386
|
+
```
|
|
348
387
|
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
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
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
const
|
|
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
|
-
|
|
376
|
-
|
|
429
|
+
### 비정렬 수집기 선택 (성능 우선)
|
|
430
|
+
```typescript
|
|
431
|
+
// 순서 보장이 필요하지 않은 경우
|
|
432
|
+
const highPerformance = data
|
|
433
|
+
.filter(predicate)
|
|
434
|
+
.map(mapper)
|
|
435
|
+
.toUnoredered(); // 최고 성능
|
|
377
436
|
```
|
|
378
437
|
|
|
379
|
-
###
|
|
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
|
-
|
|
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
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
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
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
{ value: 45 }
|
|
466
|
-
]);
|
|
452
|
+
### 통계 분석 선택 (숫자 계산)
|
|
453
|
+
```typescript
|
|
454
|
+
// 통계 분석이 필요한 경우
|
|
455
|
+
const stats = data
|
|
456
|
+
.toNumericStatistics(); // 숫자 통계
|
|
467
457
|
|
|
468
|
-
const
|
|
469
|
-
|
|
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
|
-
|
|
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
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
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 개발자에게 강력하고 유연한 스트림 처리 기능을 제공하며 함수형 프로그래밍의 이점과 타입 안전성을 결합합니다.
|