-
Kotlin Collection - 2.Transformation Operation(map, zip, flatten)Kotlin 2021. 10. 17. 19:33
저번 게시물에 이어 Kotlin Collection의 가장 매력적인 요소라 생각하는 Transformation Operation에 대해서 정리해보겠습니다.
- Kotlin Transformation Operation란?
Kotiln은 Collection을 다양한 형태로 변형할 수 있는 확장 함수를 제공합니다. Kotlin을 사용해보셨다면 접해봤을 map, filter, flatMap과 같은 것들입니다.
이러한 확장 함수들을 사용해서 반복문과 조건문에서 벗어나 아주 간결하고 명확한 코드를 작성할 수 있습니다. 람다와 체이닝 등의 개념들이 이러한 목표를 달성하는데 도움을 줍니다. Transformation Operation은 연속해서 적용할 수 있고, 람다식을 인자로 전달해서 동작하기 때문이죠.
이러한 오퍼레이션들을 적용하면 기존 collection이 변환되는 것이 아니라 새로운 collection을 반환합니다.
1. Map
Map은 특정 Collection으로부터 새로운 Collection을 만들어내는 오퍼레이션입니다. 특정 람다를 인자로 전달하면 기존 Collection으로부터 새로운 Collection이 만들어지는 형태입니다.
위 이미지는 map의 구현 코드입니다. Iterable을 확장한 함수로 정의되있고, 인자로 transform이라고 명명한 함수를 전달합니다. 그리고 List를 반환하게 되죠.
val stringList = listOf("a", "b", "c") println(stringList.map { it.toUpperCase() }) println(stringList)
위와 같은 코드를 작성하면 map의 인자로 전달한 람다식에 따라 새로운 Collection이 만들어지면서 결과가 출력됩니다.
단, 기존 Collection은 변하지 않습니다. 함수형 프로그래밍에서는 side effect를 줄이고자 외부 데이터에 대한 변화를 최대한 줄이고자 합니다. 이러한 동작도 함수형 프로그래밍의 철학을 반영한 것이라고 생각됩니다.
Collection을 사용하다보면 Index도 같이 사용해서 값에 대한 처리를 하는 경우가 많습니다. map의 변형 형태로 mapIndexed 오퍼레이션을 사용하면 index도 람다 안에서 사용할 수 있습니다.
println(stringList.mapIndexed { index: Int, s: String -> "this is ${index+1} ${s.toUpperCase()}" })
위와 같이 코드를 작성하면 람다 내부에서 index와 value를 모두 사용해서 새로운 값을 정의할 수 있습니다.
출력 결과는 다음과 같습니다.
그 외에 mapNotNull이나 mapIndexedNotNull과 같은 오퍼레이션을 사용하면 결과물에서 null 값은 포함하지 않은 Collection을 생성할 수 있습니다.
2. Zip
Zip 오퍼레이션은 두 개의 Collection을 합쳐서 Pairs (두 개의 값을 가진 Kotlin의 클래스)를 가진 새로운 Collection을 반환합니다. 즉 두개의 Collection의 값들을 합쳐서 어떤 특정 Collection을 만드는 것입니다.
말 그대로 두 개 Collection 간 특정 처리를 하고 싶을 때 사용하면 유용합니다. 만약, 각 Collection의 크기가 다르다면, 작은 쪽의 Collection의 크기만큼 새로운 Collection이 만들어집니다.
val firstList = listOf(1, 2, 3, 4) val secondList = listOf(7, 8, 9, 10, 11, 12) println(firstList.zip(secondList)) println(firstList zip secondList)
위와 같이 두 개의 List가 있을 때 zip을 사용하면, 두 개의 List의 값들이 합쳐진 Pairs를 가진 새로운 List가 return됩니다.
사실 Zip이 가장 유용한건 두 값을 단순히 합치는 것이 아닌, 두 Collection의 value를 불러와서 새로운 value를 만드는 것이라고 생각하는데요, Zip의 인자로 람다를 전달해주면 람다의 인자로 두 Collection의 value값을 사용할 수 있습니다.
println(firstList.zip(secondList) { first, second -> "$first + $second List!" })
위와 같이 람다를 zip의 인자로 람다를 전달해주면 각 Collection의 element를 합친 새로운 Collection을 생성할 수 있습니다.
3. Flatten
Kotlin에서 Flatten은 Collection의 Collection, 즉, Collection을 원소로 가지는 Collection을 하나의 Collection으로 만드는 것을 의미합니다. 중첩된 Collection을 하나의 Collection으로 만들어준다고 볼 수 있습니다.
val nestedList = listOf(listOf(1, 2), listOf(3, 4, 5), listOf(6, 7)) println(nestedList.flatten())
위 코드는 List를 원소로 가지는 List입니다. 이러한 List를 하나로 합치는 것이 flatten이라고 볼 수 있습니다.
코드를 실행시키면 다음과 같은 결과가 출력됩니다.
'Kotlin' 카테고리의 다른 글
Kotlin Delegation 사용과 예시 (2) 2022.06.05 Kotlin Collection - 3.Sequences (0) 2021.10.24 Kotlin Collection - 1. 컬렉션 생성 (0) 2021.10.11 Const val과 val의 차이 (0) 2021.09.03 Kotlin의 고차 함수 (0) 2021.05.23