출처: https://www.boostcourse.org/mo234/lecture/154318?isDesc=false
코틀린은 컬렉션을 위한 많은 확장 함수를 제공하고 있다.
package chap05.section3
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")
println(list2 + 1)
println(list2 + listOf(5, 6, 7))
// 요소 삭제 (원본은 그대로)
println(list2 - 1)
println(list2 - listOf(3, 4))
// 맵의 경우
println(map1 + Pair("bye", 4))
println(map1 - "hello")
println(map1 + mapOf("Apple" to 4, "Orange" to 5))
println(map1 - listOf("hi", "hello"))
}
[one, two, three, four]
[1, 3, 4, 1]
[1, 3, 4, 5, 6, 7]
[3, 4]
[1]
{hi=1, hello=2, goodbye=3, bye=4}
{hi=1, goodbye=3}
{hi=1, hello=2, goodbye=3, Apple=4, Orange=5}
{goodbye=3}
package chap05.section3
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++")
list.forEach { print("$it") }
println()
list.forEachIndexed { index, value -> println("list[$index] : $value") }
val returnedList = list.onEach { print(it) }
println()
val returnedMap = map.onEach { println("key: ${it.key}, value: ${it.value}") }
println(returnedList)
println(returnedMap)
}
123456
list[0] : 1
list[1] : 2
list[2] : 3
list[3] : 4
list[4] : 5
list[5] : 6
123456
key: 11, value: Java
key: 22, value: Kotlin
key: 33, value: C++
[1, 2, 3, 4, 5, 6]
{11=Java, 22=Kotlin, 33=C++}
fold, reduce: 초기값과 정해진 식에 따라 요소를 처리하기 위한 것
foldRight, reduceRight: 위의 개념과 동일하지만 요소의 마지막 (오른쪽) 요소에서 처음 요소 순으로 적용하다.
package chap05.section3
fun main() {
val list = listOf(1, 2, 3, 4, 5 ,6)
// 초기값에 따라 누적합 구하기
println(list.fold(4) { total, next -> total + next }) // 4 + (1 + 2 + ... + 6) = 25
println(list.fold(1) { total, next -> total * next }) // 1 * (1 * 2 * ... * 6) = 720
// 역방향 (뒤에서 앞으로)
println(list.foldRight(4) { total, next -> total + next })
println(list.foldRight(1) { total, next -> total * next })
// 초기값 없이 첫번째 요소부터 시작
println(list.reduce { total, next -> total + next }) // 1 + 2 + ... + 6 = 21
println(list.reduceRight { total, next -> total + next }) // 6 + 5 + ... + 1 = 21
}
25
720
25
720
21
21
package chap05.section3
fun main() {
val list = listOf(1, 2, 3, 4, 5, 6)
val listWithNull = listOf(1, null, 3, null, 5, 6)
// 컬렉션에 주어진 식을 적용하여 새로운 컬렉션 반환
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]
// null을 제외하고 식을 적용해 새로운 컬렉션 반환
println(listWithNull.mapNotNull { it?.times(2) }) // [2, 6, 10, 12]
}
각 요소에 식을 적용한 후 이것을 다시 하나로 합쳐서 새로운 컬렉션을 반환
package chap05.section3
fun main() {
val list = listOf(1, 2, 3, 4, 5, 6)
// 각 요소에 식을 적용한 뒤에 이를 다시 하나로 합쳐서 새로운 컬렉션 반환
println(list.flatMap { listOf(it, 'A') })
// toList(): 요소를 분해하여 리스트로 반환
val result = listOf("abc", "12").flatMap { it.toList() }
println(result)
}
[1, A, 2, A, 3, A, 4, A, 5, A, 6, A]
[a, b, c, 1, 2]
주어진 식에 따라 요소를 그룹화 하고 이것을 다시 Map으로 반환
val grpMap = list.groupBy { if(it % 2 == 0) "even" else "odd" }
println(grpMap)
{odd=[1, 3, 5], even=[2, 4, 6]}
package chap05.section3
fun main() {
val list = listOf(1, 2, 3, 4, 5, 6)
// 인덱스에 해당하는 요소 반환
println("elementAt: " + list.elementAt(1))
// 인덱스를 벗어나는 경우, 주어진 람다식에 따른 결과 반환
println("elementAtOrElse: " + list.elementAtOrElse(10) { 2 * it })
// 인덱스를 벗어나면 null 반환
println("elementAtOrNull: " + list.elementAtOrNull(10))
}
elementAt: 2
elementAtOrElse: 20
elementAtOrNull: null
시드 값에 의해 시작 요소의 값이 결정됨.
package chap05.section3
fun main() {
// 시드 값 1부터 시작해서 1씩 증가하는 시퀀스 생성
val nums: Sequence<Int> = generateSequence(1) { it + 1 }
// take()를 사용해서 원하는 개수만큼 요소를 획득하고
// toList()를 통해 리스트 컬렉션으로 반환
println(nums.take(10).toList())
// 10개 요소의 제곱수 구하기
val squares = generateSequence(1) { it + 1 }.map { it * it }
println(squares.take(10).toList())
// 홀수 요소 5개의 제곱수 구하기
val oddSquares = squares.filter { it % 2 != 0 }
println(oddSquares.take(5).toList())
}
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
[1, 9, 25, 49, 81]
cf) 메서드 체이닝을 연속해서 사용하면, 하나의 구문이 끝날 때마다 중간 결과로 새로운 리스트를 계속해서 만들어낸다.
package chap05.section3
fun main() {
val list1 = listOf(1, 2, 3, 4, 5)
val listDefault = list1
.map { print("map($it) "); it * it }
.filter { println("filter($it) "); it % 2 == 0 }
println(listDefault)
val listSeq = list1.asSequence()
.map { print("map($it) "); it * it }
.filter { println("filter($it) "); it % 2 == 0}
.toList()
println(listSeq)
}
map(1) map(2) map(3) map(4) map(5) filter(1)
filter(4)
filter(9)
filter(16)
filter(25)
[4, 16]
map(1) filter(1)
map(2) filter(4)
map(3) filter(9)
map(4) filter(16)
map(5) filter(25)
[4, 16]