•
Kotlin 표준 라이브러리는 변환 규칙에 따라 기존 컬렉션으로부터 새 컬렉션을 생성하는 일련의 확장 함수를 제공한다.
Map
val numbers = setOf(1, 2, 3)
println(numbers.map { it * 3 }) // [3, 6, 9]
println(numbers.mapIndexed { idx, value -> value * idx }) // [0, 2, 6]
Kotlin
복사
•
매핑 변환은 다른 컬렉션의 요소에 함수 결과를 기반으로 새 컬렉션을 생성한다.
•
기본 매핑 함수는 map() 이다.
•
이 함수는 주어진 람다 함수를 각 요소에 적용하고 그 결과 리스트를 반환한다.
•
결과의 순서는 원래 요소의 순서와 동일하다.
•
요소의 인덱스를 인수로 사용하는 변환을 적용하려면 mapIndexed() 를 사용한다.
val numbers = setOf(1, 2, 3)
println(numbers.mapNotNull { if (it == 2) null else it * 3 }) // [3, 9]
println(numbers.mapIndexedNotNull { idx, value -> if (idx == 0) null else value * idx }) // [2, 6]
Kotlin
복사
•
변환이 특정 요소에 대해 null을 생성하는 경우 mapNotNull() 함수를 호출하여 결과 컬렉션에서 null을 필터링 할 수 있다.
•
mapIndexedNotNull() 은 mapIndexed() 와 유사하다.
val numbersMap = mapOf("key1" to 1, "key2" to 2, "key3" to 3, "key11" to 11)
println(numbersMap.mapKeys { it.key.uppercase() }) // {KEY1=1, KEY2=2, KEY3=3, KEY11=11}
println(numbersMap.mapValues { it.value + it.key.length }) // {key1=5, key2=6, key3=7, key11=12}
Kotlin
복사
•
Map을 변환할 때는 두 가지 옵션이 있다.
•
Key를 변환하고 Value를 그대로 두거나 그 반대이다.
•
Key에 변환을 적용하려면 mapKeys(), Value에 변환을 적용하려면 mapValues() 를 사용한다.
Zip
val colors = listOf("red", "brown", "grey")
val animals = listOf("fox", "bear", "wolf")
println(colors zip animals) // [(red, fox), (brown, bear), (grey, wolf)]
Kotlin
복사
•
지퍼 변환은 두 컬렉션의 동일한 위치에 있는 요소들로부터 쌍을 생성한다.
•
Kotlin 표준 라이브러리에서 이는 zip() 확장 함수를 통해 수행된다.
•
컬렉션이나 배열에서 다른 컬렉션(또는 배열)을 인수로 전달할 때 zip() 은 Pair 객체의 리스트를 반환한다.
•
수신 컬렉션의 요소들이 쌍의 첫 번째 요소이다.
•
컬렉션의 크기가 다를 경우 zip() 의 결과는 더 작은 크기의 컬렉션이 된다.
•
더 큰 컬렉션의 마지막 요소는 결과에 포함되지 않는다.
println(colors.zip(animals) { color, animal -> "The ${animal.replaceFirstChar { it.uppercase() }} is $color" })
// The Fox is red, The Bear is brown, The Wolf is grey
Kotlin
복사
•
변환 함수를 사용하여 zip() 을 호출할 수도 있다.
•
이 경우 결과 리스트는 수신 요소와 인수 요소의 쌍에 대해 호출된 변환 함수의 반환 값으로 구성된다.
val numberPairs = listOf("one" to 1, "two" to 2, "three" to 3, "four" to 4)
println(numberPairs.unzip()) // (List(one, two, three, four), List(1, 2, 3, 4))
Kotlin
복사
•
쌍의 리스트에서 원래 리스트로부터 두 리스트를 구성하는 역변환인 unzip() 도 가능하다.
•
첫 번째 리스트는 원래 리스트의 각 쌍의 첫 번째 요소들로 구성되고 두 번째 리스트는 두 번째 요소들로 구성된다.
Associate
val numbers = listOf("one", "two", "three", "four")
println(numbers.associateWith { it.length }) // {one=3, two=3, three=5, four=4}
Kotlin
복사
•
연관 변환은 컬렉션 요소와 특정 Value들로부터 Map을 구축하는데 사용된다.
•
다양한 연관 유형에서 요소는 연관 Map의 Key 또는 Value가 될 수 있다.
•
기본 연관 함수인 associateWith() 는 원래 컬렉션의 요소가 Key가 되고 주어진 변환 함수로부터 생성된 Value로 Map을 생성한다.
•
두 요소가 같으면 마지막 것만 Map에 남는다.
println(numbers.associateBy { it.first().uppercaseChar() }) // {O=one, T=two, T=three, F=four}
println(numbers.associateBy(keySelector = { it.first().uppercaseChar() }, valueTransform = { it.length })) // {O=3, T=5, F=4}
Kotlin
복사
•
컬렉션 요소를 Value로 하는 Map을 구축하려면 associateBy() 를 사용한다.
•
이 함수는 요소의 값에 따라 Key를 반환하는 함수를 사용한다.
•
두 요소의 Key가 중복되면 마지막 것만 Map에 남는다.
val names = listOf("Alice Adams", "Brian Brown", "Clara Campbell")
println(names.associate { name -> parseFullName(name).let { it.lastName to it.firstName } })
Kotlin
복사
•
Key와 Value 모두 컬렉션 요소로부터 생성되는 Map을 구축하는 또 다른 방법은 associate() 함수이다.
•
이 함수는 Key와 Value가 쌍으로 생성되는 람다 함수를 받는다.
Flatten
•
중첩 컬렉션을 다룰 때 중첩된 컬렉션 요소에 대한 평면 접근을 제공하는 표준 라이브러리 함수이다.
val numberSets = listOf(setOf(1, 2, 3), setOf(4, 5, 6), setOf(1, 2))
println(numberSets.flatten()) // [1, 2, 3, 4, 5, 6, 1, 2]
Kotlin
복사
•
flatten() 은 컬렉션의 컬렉션에서 호출할 수 있으며 중첩된 컬렉션의 모든 요소로 이루어진 단일 컬렉션을 반환한다.
val containers = listOf(
StringContainer(listOf("one", "two", "three")),
StringContainer(listOf("four", "five", "six")),
StringContainer(listOf("seven", "eight"))
)
println(containers.flatMap { it.values }) // [one, two, three, four, five, six, seven, eight]
Kotlin
복사
•
flatMap() 은 중첩 컬렉션을 처리할 수 있는 유연한 방법을 제공한다.
•
이 함수는 컬렉션 요소를 다른 컬렉션으로 매핑하는 함수를 받는다.
•
결과적으로 flatMap() 은 모든 요소에 대한 반환 값의 단일 리스트를 반환한다.
•
flatMap() 은 map() 을 호출한 후 그 결과를 flatten() 하는 것처럼 작동한다.
String representation
val numbers = listOf("one", "two", "three", "four")
println(numbers) // [one, two, three, four]
println(numbers.joinToString()) // one, two, three, four
val listString = StringBuffer("The list of numbers: ")
numbers.joinTo(listString)
println(listString) // The list of numbers: one, two, three, four
Kotlin
복사
•
컬렉션 내용을 읽기 쉬운 형식으로 가져오려면 컬렉션을 문자열로 변환하는 함수인 joinToString() 및 joinTo() 를 사용하라.
•
joinToString() 은 제공된 인수에 따라 컬렉션 요소로부터 단일 문자열을 생성한다.
•
joinTo() 는 동일한 작업을 수행하지만 결과를 주어진 Appendable 객체에 추가한다.
•
기본 인수로 호출하면 이 함수들은 컬렉션의 요소 문자열 표현을 쉼표로 구분하여 반환하는 toString()을 호출하는 것과 유사하다.
println(numbers.joinToString(separator = " | ", prefix = "start: ", postfix = ": end"))
// start: one | two | three | four: end
Kotlin
복사
•
사용자 정의 문자열 표현을 구축하려면 함수 인수인 separator, prefix, postfix 의 매개변수를 지정할 수 있다.
•
결과 문자열은 prefix로 시작하고 postfix로 끝난다.
•
구분자는 마지막 요소를 제외한 각 요소 뒤에 온다.
val numbers = (1..100).toList()
println(numbers.joinToString(limit = 10, truncated = "<...>"))
// 1, 2, 3, 4, 5, 6, 7, 8, 9, 10<...>
Kotlin
복사
•
더 큰 컬렉션의 경우 결과에 포함될 요소의 수를 지정할 수 있는 limit를 설정할 수 있다.
•
컬렉션 크기가 limit를 초과할 경우 나머지 요소는 truncated 인수로 지정된 단일 값으로 대체된다.
println(numbers.joinToString { "Element: ${it.uppercase()}" })
// Element: ONE, Element: TWO, Element: THREE, Element: FOUR
Kotlin
복사
•
요소 자체의 표현을 사용자 정의하려면 변환 함수를 제공할 수 있다.