반응형
모든 내용은 Do it! 안드로이드 앱 프로그래밍을 바탕으로 정리한 것입니다.
[이전 포스팅]
코틀린의 컬렉션 - List, Set, Map에 대한 내용은 아래 포스팅 참고
컬렉션의 확장 함수
- 연산자(Operator) 기능의 메서드 : 더하고 빼는 등의 기능
- 집계(Aggregator) 기능의 메서드 : 최대, 최소, 집합, 총합 등의 계산 기능
- 검사(Check) 기능의 메서드 : 요소를 검사하고 순환하는 기능
- 필터(Filtering) 기능의 메서드 : 원하는 요소를 골라내는 기능
- 변환(Transforming) 기능의 메서드 : 뒤집기, 정렬, 자르기 등의 변환 기능
컬렉션의 연산
fun main() {
val list1: List<String> = listOf("one", "two", "three")
val list2: List<Int> = listOf(1, 3, 4)
val map1 = mapOf("hi" to 1, "hello" to 2, "Goodbye" to 3)
println(list1 + "four") // [one, two, three, four]
println(list2 + 1) // [1, 3, 4, 1]
println(list2 + listOf(5, 6, 7)) // [1, 3, 4, 5, 6, 7]
println(list2 - 1) // [3, 4]
println(list2 - listOf(3, 4, 5)) // [1] - 일치하는 요소 제거
println(map1 + Pair("Bye", 4)) // {hi=1, hello=2, Goodbye=3, Bye=4}
println(map1 - "hello") // {hi=1, Goodbye=3}
println(map1 + mapOf("Apple" to 4, "Orange" to 5)) // {hi=1, hello=2, Goodbye=3, Apple=4, Orange=5}
println(map1 - listOf("hi", "hello")) // {Goodbye=3} - 일치하는 값 제거
}
- 일반적인 연산자 +와 -를 사용해 컬렉션 요소를 더하거나 뺄 수 있음
- 연산자 +와 -를 사용해 컬렉션 자체를 더하거나 뺄 수 있음
- listOf(), Pair(), mapOf() 등을 더하거나 빼는 방법으로 요소를 병합하거나 제거할 수 있음
컬렉션의 집계
fun main() {
val list = listOf(1, 2, 3, 4, 5, 6)
val listPair = listOf(Pair("A", 300), Pair("B", 200), Pair("C", 100))
val map = mapOf(11 to "Java", 22 to "Kotlin", 33 to "C++")
...
}
위의 3개의 컬렉션을 예시로 하여 집계 확장 함수를 설명합니다!
요소의 순환
list.forEach { print("$it") }
println()
list.forEachIndexed { index, value -> println("index[$index]: $value") }
val returnedList = list.onEach { print(it)}
println()
val returnedMap = map.onEach { println("key: ${it.key}, value: ${it.value}") }
println("returnedList = $returnedList") // returnedList = [1, 2, 3, 4, 5, 6]
println("returnedMap = $returnedMap") // returnedMap = {11=Java, 22=Kotlin, 33=C++}
- forEach : 각 요소를 람다식으로 처리 (컬렉션 반환X)
- forEachIndexed : 각 요소와 인덱스를 람다식으로 처리
- onEach : 각 요소를 람다식으로 처리하고 각 컬렉션을 반환받음
요소의 개수
println(list.count { it % 2 == 0}) // 3
println(list.count()) // 6
- count : 특정 조건에 일치하는 요소의 개수를 반환함
- 요소를 it으로 받아 1, 2, 3, 4, 5, 6 중에서 count에 의해 람다식 조건이 짝수인 요소의 개수를 반환함
최댓값과 최솟값
println(list.max()) // 6
println(list.min()) // 1
println("maxBy: "+map.maxBy { it.key }) // maxBy: 33=C++
println("minBy: "+map.minBy { it.key }) // minBy: 11=Java
- max / min : 최댓값 요소와 최솟값 요소 반환
- maxBy / minBy : 최댓값과 최솟값으로 나온 요소 it에 대한 식의 결과
- 람다식에 의해 컬렉션을 처리하며, 위의 예제에서는 키를 기준으로 최대, 최소를 반환함
요소에 정해진 식
println(list.fold(4) { total, next -> total + next }) // 4 + 1 + ... + 6 = 25
println(list.fold(1) { total, next -> total * next }) // 1 * 1 * ... * 6 = 720
println(list.foldRight(4) { total, next -> total + next }) // 25
println(list.foldRight(1) { total, next -> total * next }) // 720
println(list.reduce { total, next -> total + next }) // 21
println(list.reduceRight { total, next -> total + next }) // 21
- fold(초기값) : list의 모든 요소에 대해 초기값이 정해지고 모든 요소가 처리됨
- foldRight(초기값) : fold와 동일하지만 4+6+5+...+1과 같이 요소의 오른쪽부터 처리됨
- reduce : fold와 동일하지만 초기값을 사용하지 않음
- reduceRight : foldRight와 동일하지만 초기값을 사용하지 않음
요소 합산
println(listPair.sumBy { it.second }) // 600
- sumBy : 식에서 도출된 모든 요소를 합한 결과 반환
- 위의 예제에서는 Pair로 묶인 요소의 두번째(second)를 합한 결과가 반환됨
컬렉션의 검사
fun main() {
val list = listOf(1, 2, 3, 4, 5, 6)
val listPair = listOf(Pair("A", 300), Pair("B", 200), Pair("C", 100))
val map = mapOf(11 to "Java", 22 to "Kotlin", 33 to "C++")
...
}
위의 3개의 컬렉션을 예시로 하여 검사 확장 함수를 설명합니다!
요소의 일치 여부 검사
println(list.all { it < 10 }) // true
println(list.all { it % 2 == 0 }) // false
println(list.any { it % 2 == 0 }) // true
println(list.any { it > 10 }) // false
- all : 람다식에서 모든 요소가 일치할 때 true 반환
- any : 최소한 하나 혹은 그 이상의 특정 요소가 일치하면 true 반환
특정 요소의 포함 / 존재 여부 검사
println("contains: " + list.contains(2)) // contains: true
println(2 in list) // true
println(map.contains(11)) // true
println(11 in map) // true
println("containsAll: "+list.containsAll(listOf(1, 2, 3))) // containsAll: true
- contains : 요소가 포함되어 있는지를 검사하며, 포함되어 있으면 true 반환
- 범위 연산자 in을 사용해서 요소의 포함 여부를 확인할 수 있음
- containsAll : 모든 요소가 포함되어 있는지 검사하며, 포함되어 있으면 true 반환
println("none: "+list.none()) // none: false
println("none: "+list.none { it > 6 }) // none: true
println(list.isEmpty()) // false
println(list.isNotEmpty()) // true
- none() : 검사했을 때 요소가 없으면 true, 있으면 false 반환
- isEmpty() : 컬렉션이 비어있으면 true를 반환
- isNotEmpty() : 컬렉션이 비어있지 않다면 true를 반환
컬렉션의 필터
fun main() {
val list = listOf(1, 2, 3, 4, 5, 6)
val listMixed = listOf(1, "Hello", 3, "World", 5, 'A')
val listWithNull = listOf(1, null, 3, null, 5, 6)
val listRepeated = listOf(2, 2, 3, 4, 5, 5, 6)
val map = mapOf(11 to "Java", 22 to "Kotlin", 33 to "C++")
...
}
위의 5개의 컬렉션을 예시로 하여 필터 확장 함수를 설명합니다!
특정 요소 골라내기
println(list.filter { it % 2 == 0 }) // [2, 4, 6]
println(list.filterNot { it % 2 == 0 }) // [1, 3, 5]
println(listWithNull.filterNotNull()) // [1, 3, 5, 6]
- filter() : 식에 따라 요소 골라내는 메서드
- filterNot() : 식 이외에 요소를 골라내는 메서드
- filterNotNull() : 컬렉션에서 null을 제외하기 위한 메서드
println("filterIndexed: "+list.filterIndexed { index, value -> index != 1 && value % 2 == 0 })
// filterIndexed: [4, 6]
val mutList = list.filterIndexedTo(mutableListOf()) { index, value -> index != 1 && value % 2 == 0 }
println("filterIndexedTo: $mutList")
// filterIndexedTo: [4, 6]
- filterIndexed() : 식의 결과를 인덱스와 함께 추출
- filterIndexedTo() : 인덱스를 포함한 결과를 추출 후 컬렉션으로 반환
println("filterKeys: " + map.filterKeys { it != 11 }) // filterKeys: {22=Kotlin, 33=C++}
println("filterValues: " + map.filterValues { it == "Java" }) // filterValues: {11=Java}
- filterKeys : 요소를 it으로 받아서 키에 대한 조건에 맞는 부분을 반환
- filterValues : 요소를 it으로 받아서 값에 대한 조건에 맞는 부분을 반환
println("filterIsInstance: " + listMixed.filterIsInstance<String>()) // filterIsInstance: [Hello, World]
- filterIsInstance<T>() : 여러 자료형 중 원하는 자료형(T)을 골라낼 수 있는 필터
특정 범위 자르거나 반환하기
println("slice: " + list.slice(listOf(0, 1, 2))) // slice: [1, 2, 3]
- slice() : 특정 범위의 인덱스를 가진 List의 인자를 사용해 기존 List에서 요소들을 잘라냄
println(list.take(2)) // [1, 2]
println(list.takeLast(2)) // [5, 6]
println(list.takeWhile { it < 3 }) // [1, 2]
- take(n) : n개의 요소를 가진 List를 반환
- takeLast(n) : 마지막에서 부터 n개의 요소를 가진 List를 반환
- takeWhile : 조건식에 따라 해당 요소를 반환
특정 요소 제외
println(list.drop(3)) // [4, 5, 6]
println(list.dropWhile { it < 3 }) // [3, 4, 5, 6]
println(list.dropLastWhile { it > 3 }) // [1, 2, 3]
- drop(n) : 앞의 n개의 요소를 제외한 List를 반환
- dropWhile, dropLastWhile : 조건식에 따라 요소를 제외하고 List를 반환
각 요소 반환
println("component1(): " + list.component1()) // component1(): 1
- componentN() : N번째 요소 반환
- 여기서 N은 인덱스 번호가 아닌 요소의 순서 번호
합집합과 교집합
println("distinct: " + listRepeated.distinct())
// val listRepeated = listOf(2, 2, 3, 4, 5, 5, 6)
// distinct: [2, 3, 4, 5, 6]
println("intersect: " + list.intersect(listOf(5, 6, 7, 8))) // intersect: [5, 6]
- distinct() : 여러 중복 요소가 있는 경우 1개로 취급해 다시 컬렉션을 List로 반환함 == 합집합
- intersect() : 겹치는 요소만 골라내 List로 반환 == 교집합
요소의 매핑
fun main() {
val list = listOf(1, 2, 3, 4, 5, 6)
val listWithNull = listOf(1, null, 3, null, 5, 6)
...
}
위의 2개의 컬렉션으로 요소의 매핑 확장 함수를 설명합니다!
println(list.map { it * 2 }) // [2, 4, 6, 8, 10, 12]
val mapIndexed = list.mapIndexed { index, it -> index * it }
println(mapIndexed) // [0, 2, 6, 12, 20, 30]
println(listWithNull.mapNotNull { it?.times(2) })
// [2, 6, 10, 12]
- .map() : 식을 적용해 새로운 컬렉션을 만들 수 있게 하는 메서드
- forEach()와 비슷해보이지만 주어진 컬렉션을 전혀 건드리지 않는다는 점에서 더 안전함
- mapIndexed : 인덱스를 포함하고 주어진 식을 적용하여 새로운 컬렉션 반환
- mapNotNull : null을 제외하고 식을 적용해 새로운 컬렉션 반환
println(list.flatMap { listOf(it, 'A') }) // [1, A, 2, A, 3, A, 4, A, 5, A, 6, A]
val result = listOf("abc", "12").flatMap { it.toList() }
println(result) // [a, b, c, 1, 2]
- flatMap : 각 요소에 식을 적용한 후 다시 합쳐 새로운 컬렉션을 반환
val grapMap = list.groupBy { if (it % 2 == 0) "even" else "odd" }
println(grapMap) // {odd=[1, 3, 5], even=[2, 4, 6]}
- groupBy : 주어진 식에 따라 요소를 그룹화하고 이것을 다시 Map으로 반환함
요소의 처리와 검색
fun main() {
val list = listOf(1, 2, 3, 4, 5, 6)
val listPair = listOf(Pair("A", 300), Pair("B", 200), Pair("C", 100), Pair("D", 200))
val listRepeated = listOf(2, 2, 3, 4, 5, 5, 6)
...
}
위의 3개의 컬렉션으로 요소의 처리, 검색 확장 함수를 설명합니다!
println("elementA: " + list.elementAt(1)) // elementA: 2
println("elementAtOrElse: " + list.elementAtOrElse(10, { 2 * it })) // elementAtOrElse: 20
println("elementAtOrNull: " + list.elementAtOrNull(10)) // elementAtOrNull: null
- elementAt(N) : 인덱스에 해당하는 요소 반환
- 범위를 벗어나면 안됨
- 범위를 벗어나면 IndexOutOfBoundsException 오류 발생
- elementAtOrElse : 인덱스를 벗어나는 경우 식에 따라 결과를 반환함
- elementAtOrNull : 인덱스를 벗어나는 경우 null을 반환함
println("first: " + listPair.first { it.second == 200 }) // first: (B, 200)
println("last: " + listPair.last { it.second == 200 }) // last: (D, 200)
println("firstOrNull: " + listPair.firstOrNull { it.first == "E" }) // firstOrNull: null
println("lastOrNull: " + listPair.lastOrNull { it.first == "E" }) // lastOrNull: null
- first / last : 식에 일치하는 첫/마지막 요소 반환
- firstOrNull / lastOrNull : 식에 일치하지 않은 경우 null을 반환
println("indexOf: " + list.indexOf(4)) // indexOf: 3
println("indexOfFirst: " + list.indexOfFirst { it % 2 == 0 }) // indexOfFirst: 1
println("lastIndexOf: " + listRepeated.lastIndexOf(5)) // lastIndexOf: 5
println("indexOfLast: " + list.indexOfLast { it % 2 == 0 }) // indexOfLast: 5
- indexOf / lastIndexOf : 주어진 요소에 일치하는 첫/마지막 인덱스를 반환함
- indexOfFirst / indexOfLast : 람다식에 일치하는 첫/마지막 요소의 인덱스를 반환, 없으면 -1 반환
println("single: " + listPair.single { it.second == 100 }) // single: (C, 100)
println("singleOrNull: " + listPair.singleOrNull { it.second == 500 }) // singleOrNull: null
- single : 해당 조건식에 일치하는 요소를 하나 반환함
- 일치하는 요소가 하나 이상인 경우 예외가 발생할 수 있음
- singleOrNull : 조건식에 일치하는 요소가 없거나 일치하는 요소가 하나 이상이면 null을 반환함
println("binarySearch: " + list.binarySearch(3)) // binarySearch: 2
println("find: " + list.find { it > 3 }) // find: 4
- binarySearch(n) : 인자로 주어진 요소에 대해 이진 탐색 후 인덱스를 반환함
- 중복된 요소가 있는 경우에 해당 요소가 원하는 순서에 있는 요소인지는 보장하지 않음
- find : 조건식에 만족하는 첫 번째 검색된 요소를 반환하고, 없으면 null을 반환함
컬렉션의 변환
fun main() {
val list1 = listOf(1, 2, 3, 4, 5, 6)
val list2 = listOf(2, 2, 3, 4, 5, 5, 6, 7)
println(list1.union(list2)) // [1, 2, 3, 4, 5, 6, 7]
println(list1.plus(list2)) // [1, 2, 3, 4, 5, 6, 2, 2, 3, 4, 5, 5, 6, 7]
val part = list1.partition { it % 2 == 0 }
println(part) // ([2, 4, 6], [1, 3, 5])
val zip = list1.zip(listOf(7, 8))
println(zip) // [(1, 7), (2, 8)]
}
- union() : 두 List 컬렉션을 병합하고, 중복된 요소 값은 하나만 유지함 → Set 컬렉션을 반환함
- plus() / + : 중복 요소를 포함하여 합침 → List 컬렉션을 반환함
- partition : 조건식의 결과(boolean)에 따라 List 컬렉션을 2개로 분리함
- true에 해당하는 값이 첫 번째 위치에 반환, false에 해당하는 값은 두 번째 위치에 반환
- 분리된 2개의 List 컬렉션은 Pair로 반환됨
- zip() : 2개의 컬렉션에서 동일한 인덱스 위치한 값끼리 Pair를 만들어 반환함
- 요소의 개수가 가장 적은 컬렉션에 맞춰 Pair가 구성됨
순서 정렬
fun main() {
val unsortedList = listOf(3, 2, 7, 5)
println(unsortedList.reversed()) // [5, 7, 2, 3]
println(unsortedList.sorted()) // [2, 3, 5, 7]
println(unsortedList.sortedDescending()) // [7, 5, 3, 2]
println(unsortedList.sortedBy { it % 3 }) // [3, 7, 2, 5]
println(unsortedList.sortedByDescending { it % 3 }) // [2, 5, 7, 3]
}
- reversed() : 요소의 순서를 거꾸로하여 반환
- sorted() : 요소를 작은 수에서 큰 수로 반환하고, 알파벳순으로 정렬한 후 정렬된 컬렉션을 반환
- sortedBy() : 특정한 비교식에 의해 정렬된 컬렉션을 반환
- sortedDescending / sortedByDesceding : 요소를 큰 수에서 작은 수로, z부터 a 순서로 정렬해서 반환
반응형
'Kotlin > Kotlin 프로그래밍' 카테고리의 다른 글
[Kotlin] 클로저와 표준 함수 let, also, apply, run, with (0) | 2021.07.08 |
---|---|
[Kotlin/Coroutine] 코루틴(Coroutine)의 개념과 사용 (0) | 2021.06.16 |
[Kotlin/Coroutine] 코루틴(Coroutine) - 동시성 프로그래밍 (0) | 2021.06.03 |
[Kotlin] 코틀린의 시퀀스(Sequence) (2) | 2021.06.02 |
[Kotlin] 컬렉션(Collection) - Set, Map (0) | 2021.05.26 |
[Kotlin] 컬렉션(Collection) - List (0) | 2021.05.24 |
[Kotlin] 문자열(String) (0) | 2021.05.21 |
[Kotlin] 배열(Array) (0) | 2021.05.18 |
댓글