컴퓨터 언어/kotlin

Collection Transformations

이건욱 2020. 5. 22. 16:41

Kotlin Standard Library에서는 collection에서 transformation에 대한 함수를 제공합니다.

이 함수들은 기존에 있던 값에 transformation에 대한 규칙을 적용시켜서 새로운 collection을 만듭니다.

 

Mapping

가장 기본적인 Mapping 함수는 map()입니다.

map 함수는 lambda 함수를 제공을 하고 각각에 대해서 돌면서 결과를 Return 합니다.

 

value가 아닌 index도 같이 포함을 하고싶은경우에는 mapIndexed()을 사용할수가 있습니다.

val numbers = setOf(1, 2, 3)
println(numbers.map { it * 3 })
println(numbers.mapIndexed { idx, value -> value * idx })

 

기본적으로 map() 함수일 경우에는 Null일 경우에도 포함을 합니다.

따라서 Null을 제거하고 보여주고 싶은 경우에는 mapNotNull() or mapIndexedNotNull()을 사용하면 됩니다.

 

Map Collection에 대해서는 두가지를 통해 할수가 있습니다.

먼저 mapKeys() 을 통해서 key 에 대해서 할수가 있습니다.

그 다음으로 mapValues() 을 통해서는 value을 대해서 할수가 있습니다.

val numbersMap = mapOf("key1" to 1, "key2" to 2, "key3" to 3, "key11" to 11)
println(numbersMap.mapKeys { it.key.toUpperCase() })
println(numbersMap.mapValues { it.value + it.key.length })

 

Zipping

두개의 collection 있을 경우 zip()을 통해서 같은 포지션에 pair 객체를 만들수 있습니다.

만약에 둘중에 collection에서 사이즈가 맞지 않는 다면 더 작은 사이즈를 기준으로 하게 됩니다.

 

사용은 아래와 같이 할수가 있습니다.

val colors = listOf("red", "brown", "grey")
val animals = listOf("fox", "bear", "wolf")
println(colors zip animals)

val twoAnimals = listOf("fox", "bear")
println(colors.zip(twoAnimals))

 

그리고 그 Pair로 변환한 객체에 대해서 추가적인 작업을 더 하고 싶은 경우에는 아래와 같이 할수가 있습니다.

val colors = listOf("red", "brown", "grey")
val animals = listOf("fox", "bear", "wolf")

println(colors.zip(animals) { color, animal -> "The ${animal.capitalize()} is $color"})

 

다음으로 기존에서는 두개를 하나로 만드는 작업을 했다면 이제는 unzip()을 통해서 하나를 두개로 만들수가 있습니다.

val numberPairs = listOf("one" to 1, "two" to 2, "three" to 3, "four" to 4)
println(numberPairs.unzip())

 

Association

Association을 통해서 Collection으로 부터 Map을 만들수가 있습니다.

 

가장 기본적인 함수는 associateWith()입니다. 

이 함수는 collection에 값이 Key로 새로운 Map을 만듭니다. 그리고 Value는 주어진 lambda함수안에서 통해 줄수가 있습니다.

val numbers = listOf("one", "two", "three", "four")
println(numbers.associateWith { it.length })

//{one=3, two=3, three=5, four=4}

 

이전에는 lambda 함수를 통해서 value 을 설정을 했다면 이제는 key or key value 로 설정을 할수가 있습니다.

    val numbers = listOf("one", "two", "three", "four")

    println(numbers.associateBy { it.first().toUpperCase() })
    println(numbers.associateBy(keySelector = { it.first().toUpperCase() }, valueTransform = { it.length }))
    
    {O=one, T=three, F=four}
	{O=3, T=5, F=4}

 

또다른 방법으로는 associate()을 통해서 Pair 객체로 넘길수가 있습니다.

하지만 퍼포먼스에 영향을 미치기 때문에 성능에 크게 상관이 없는 작업에 사용을 해야합니다.

 

val names = listOf("Alice Adams", "Brian Brown", "Clara Campbell")
println(names.associate { it + "_key" to it + "_value" })

{Alice Adams_key=Alice Adams_value, Brian Brown_key=Brian Brown_value, Clara Campbell_key=Clara Campbell_value}

 

Flattening

여러개의 collection에서 하나의 collection으로 포함시켜서 보여주고 싶을 때 사용이 가능합니다.

 

flatten()

val numberSets = listOf(setOf(1, 2, 3), setOf(4, 5, 6), setOf(1, 2))
println(numberSets.flatten())

flatMap()

println(list.flatMap {
            val list = mutableListOf<String>()

            list.add(it + "0")
            list.add(it + "1")
            list
        }) // [1230, 1231, 450, 451]

 

String representation

Collection content을 검색을 하기 위해서 읽을 수 있는 형식으로 변경을 할려면 joinToString() and joinTo()을 사용할수가 있습니다

 

 val numbers = listOf("one", "two", "three", "four")

        println(numbers)
        println(numbers.joinToString())

        val listString = StringBuffer("The list of numbers: ")
        numbers.joinTo(listString)
        println(listString)
        
        
[one, two, three, four]
one, two, three, four
The list of numbers: one, two, three, four
  val numbers = listOf("one", "two", "three", "four")
        println(numbers.joinToString(separator = " | ", prefix = "start: ", postfix = ": end"))
        
        //start: one | two | three | four: end
    val numbers = (1..100).toList()
    println(numbers.joinToString(limit = 10, truncated = "<...>"))
        
    1, 2, 3, 4, 5, 6, 7, 8, 9, 10, <...>
        val numbers = listOf("one", "two", "three", "four")
        println(numbers.joinToString { "Element: ${it.toUpperCase()}"})
        
        Element: ONE, Element: TWO, Element: THREE, Element: FOUR