✅ Kotlin은 컬렉션을 효율적으로 다룰 수 있는 유틸 함수들을 제공합니다.
🔹 zip — 두 리스트 병합
val names = listOf("Alice", "Bob")
val scores = listOf(90, 80)
val zipped = names.zip(scores) // [(Alice, 90), (Bob, 80)]
- 두 컬렉션을 같은 인덱스로 Pair로 묶음
- 크기가 다르면 짧은 쪽 기준
🔸 순회 방법
for ((name, score) in zipped) {
println("$name: $score")
}
val names = listOf("Alice", "Bob")
val scores = listOf(90, 80)
val zipped = names.zip(scores) // [(Alice, 90), (Bob, 80)]
- 두 컬렉션을 같은 인덱스로 Pair로 묶음
- 크기가 다르면 짧은 쪽 기준
🔸 unzip — 분리
val (names2, scores2) = zipped.unzip()
🔸 zipWithNext
val list = listOf(1, 4, 9)
val diff = list.zipWithNext { a, b -> b - a } // [3, 5]
- 연속된 두 값을 묶어 처리할 때 유용함
🔹 flatMap — 2차원 리스트 평탄화 및 변환
val nested = listOf(listOf(1, 2), listOf(3, 4))
val flat = nested.flatMap { it } // [1, 2, 3, 4]
- map + flatten을 동시에 수행
- 중첩 리스트 구조를 1차원으로 펼침
val transformed = nested.flatMap { it.map { n -> n * 2 } } // [2, 4, 6, 8]
🔸 flatten vs flatMap
val nested = listOf(listOf(1, 2), listOf(3, 4))
nested.flatten() // [1, 2, 3, 4]
nested.flatMap { it } // 동일 결과
nested.flatMap { it.map { x -> x * 2 } } // [2, 4, 6, 8]
flatten(): 중첩 리스트(List)를 1차원(List)으로 변환 (요소 변환 없이 단순 펼침)flatMap(): 중첩 리스트를 펼치면서 내부 요소에 변환(map)을 적용 (map + flatten의 역할)
🔹 chunked — 고정 크기로 잘라서 리스트로
val list = (1..10).toList()
val chunked = list.chunked(3) // [[1,2,3], [4,5,6], [7,8,9], [10]]
- 주어진 크기 단위로 쪼갬
- 마지막은 남은 크기만큼 포함
🔹 windowed — 슬라이딩 윈도우 처리
val list = (1..10).toList()
val win1 = list.windowed(size = 3, step = 1, partialWindows = false)
// [[1,2,3], [2,3,4], [3,4,5], ..., [8,9,10]]
val win2 = list.windowed(size = 3, step = 2, partialWindows = false)
// [[1,2,3], [3,4,5], [5,6,7], [7,8,9]] ← 10은 포함되지 않음
val win3 = list.windowed(size = 3, step = 2, partialWindows = true)
// [[1,2,3], [3,4,5], [5,6,7], [7,8,9], [9,10]] ← 끝부분 포함
- size: 윈도우 크기
- step: 슬라이딩 간격
- partialWindows: 끝부분 남은 것도 포함할지 여부
false→ 마지막 청크가 부족하면 제외true→ 남은 요소라도 포함
🔹 withIndex — 인덱스와 함께 순회
for ((i, v) in list.withIndex()) {
println("index=$i value=$v")
}
enumerate()느낌으로 자주 사용됨
🔹 groupingBy - 그룹핑 후 빈도수/누적값 집계
HashMap 없이도 빈도수 집계에 매우 유용
groupingBy { 키 추출 }로 그룹핑 기준 지정- 단독 사용x groupingBy는 Grouping<T, K> 반환
🔸 groupingBy{it}.eachCount() – 그룹별 개수 세기
val items = listOf("a", "b", "a", "c", "b", "a")
val counts = items.groupingBy { it }.eachCount()
println(counts) // {a=3, b=2, c=1}
eachCount()로 그룹별 개수 계산 (빈도수 구하기)- 실전 코테에서 문자 등장 횟수 세기 등에 매우 자주 등장
🔸 groupingBy{it}.fold(initial) {operation} – 그룹별 누적 처리 (합계, 리스트 등)
val data = listOf("a", "ab", "abc", "b", "bc")
val lengthsByFirstChar = data.groupingBy { it.first() }.fold(0) { acc, str -> acc + str.length }
// {a=6, b=4}
- 'a' 그룹: "a"(1) + "ab"(2) + "abc"(3) → 총 길이 6
- 'b' 그룹: "b"(1) + "bc"(2) → 총 길이 3
fold(initial) { acc, element -> ... }로 누적 처리- 실전에서는 그룹별 점수 합산, 값 리스트화 등에 사용 가능
🔸 groupBy vs groupingBy
- groupBy는 Map<K, List>를 반환
- groupingBy는 중간 리스트를 만들지 않고 직접 집계함
→ 메모리 효율성 ↑
✅ 고차 함수(시리즈 ⑩)와 컬렉션 유틸 함수(시리즈 ⑪) 차이
| 구분 | 고차 함수의 예 (람다 기반) | 구조 기반 컬렉션 유틸 함수 | 비고 |
|---|---|---|---|
| 핵심 개념 | 람다를 인자로 받아 조건 검사 또는 변환 수행 | 구조적으로 컬렉션을 병합·분할·슬라이딩 등 조작 | 일부 함수는 둘 다 해당 |
| 대표 함수 | map, filter, any, all, groupBy 등 |
zip, chunked, windowed, flatten, partition 등 |
flatMap은 둘 다 포함됨 |
| 목적 | 조건에 따라 요소를 필터링·변환하거나, Boolean/Map 등으로 결과 도출 | 컬렉션 구조 자체를 재구성 (쌍 만들기, 구간 분할 등) | 목적에 따라 쓰임이 다름 |
| 사용 예 | 성적 90점 이상 필터링, 문자열 길이 추출 등 | 두 리스트 병합, 3개씩 자르기, 슬라이딩 윈도우 처리 등 | 반복적 데이터 처리에 적합 |
✅ 요약 정리
| 함수 | 설명 |
|---|---|
zip |
두 리스트를 Pair로 병합 (a[i] to b[i]) |
unzip |
Pair 리스트를 두 리스트로 분리 |
zipWithNext |
인접한 요소끼리 묶기 ([a,b,c] → [(a,b), (b,c)]) |
flatMap |
중첩 리스트를 평탄화하며 변환 (List<List<T>> → List<T>) |
chunked(n) |
고정 크기 청크로 나눔 (["ab", "cd", "ef"]) |
windowed(size, step) |
슬라이딩 윈도우 구간 추출 |
withIndex |
인덱스와 함께 순회 (for ((i, v) in list.withIndex())) |
groupingBy |
그룹핑 후 빈도수/누적값 집계 (.eachCount(), .fold()) |
다음은 시리즈 ⑫: 누적 함수 (reduce, fold, scan 등) 으로 이어집니다.
'Code Odyssey' 카테고리의 다른 글
| Kotlin 코딩테스트 문법 시리즈 ⑬ : Scope Function 정리 (let, also, apply, run, takeIf) (0) | 2025.07.13 |
|---|---|
| Kotlin 코딩테스트 문법 시리즈 ⑫ : 누적 함수 정리 (reduce, fold, scan) (1) | 2025.07.12 |
| Kotlin 코딩테스트 문법 시리즈 ⑩ : 고차 함수 정리 (map, filter, any 등) (1) | 2025.07.10 |
| Kotlin 코딩테스트 문법 시리즈 ⑨ : 정렬 (기본, 조건, 다중 기준) (1) | 2025.07.09 |
| Kotlin 코딩테스트 문법 시리즈 ⑧ : 스택 / 큐 / 우선순위 큐 정리 (0) | 2025.07.08 |