-
18강. 코틀린에서 컬렉션을 함수형으로 다루는 방법BackEnd/Kotlin 2024. 4. 14. 08:00반응형
- filter와 map
- 다양한 컬렉션 처리 기능
- groupBy / associateBy
- flatten / flatMap
filter와 map
fun main() { val fruits = listOf( Fruit("사과", 1_000), Fruit("사과", 1_200), Fruit("사과", 1_200), Fruit("사과", 1_500), Fruit("바나나", 3_000), Fruit("바나나", 3_200), Fruit("바나나", 2_500), Fruit("수박", 10_000), ) val apples = fruits.filter { fruit -> fruit.name == "사과" } // filter 에서 인덱스가 필요하다면 filterIndexed 사용합니다. val apples2 = fruits.filterIndexed { idx, fruit -> println(idx) fruit.name == "사과" } // 사과의 가격들을 알기위해 filter 이후 map을 수행합니다. val applePrices = fruits.filter { fruit -> fruit.name == "사과" } .map { fruit -> fruit.price } // map에서 인덱스가 필요하다면 mapIndexed 를 사용합니다. val applePrices2 = fruits.filter { fruit -> fruit.name == "사과" } .mapIndexed { idx, fruit -> println(idx) fruit.price } }
Mapping의 결과가 null이 아닌 것만 가져오고 싶은 경우, mapNotNull을 사용하면 됩니다.
val values = fruits.filter { fruit -> fruit.name == "사과" } .mapNotNull { fruit -> fruit.nullOrVale() }
다양한 컬렉션 처리 기능
all: 조건을 모두 만족하면 true, 그렇지 않으면 false 입니다.
val isAllApple = fruits.all { fruit -> fruit.name == "사과" }
none: 조건을 모두 불만족하면 true, 그렇지 않으면 false 입니다.
val isNoApple = fruits.none { fruit -> fruit.name == "사과" }
any: 조건을 하나라도 만족하면 true, 그렇지 않으면 false 입니다.
val isBigPrice = fruits.any { fruit -> fruit.price >= 10_000 }
count: 개수를 셉니다.
val fruitCount = fruits.count()
sortedBy: (오름차순) 정렬을 합니다.
val sortedByFruit = fruits.sortedBy { fruit -> fruit.price }
sortedByDescending: (내림차순) 정렬을 합니다.
val sortedByDescFruit = fruits.sortedByDescending { fruit -> fruit.price }
distinctby: 변형된 값을 기준으로 중복을 제거합니다.
val distinctFruitNames = fruits.distinctBy { fruit -> fruit.name } .map { fruit -> fruit.name }
first: 첫번째 값을 가지고 옵니다. 값이 없을 경우 예외가 발생합니다.
firstOrNull: 첫번째 값 또는 null을 가지고 옵니다.
last: 마지막 값을 가지고 옵니다. 값이 없을 경우 예외가 발생합니다.
lastOrNull: 마지막 값 또는 null을 가지고 옵니다.
groupBy / associateBy
groupBy는 특정 key로 key에 해당하는 객체들을 매핑할 때 사용합니다. 다음은 과일이름을 key로, key에 해당하는 과일들을 value로 하는 Map을 생성하는 코드입니다.
val map: Map<String, List<Fruit>> = fruits.groupBy { fruit -> fruit.name }
key와 value를 동시에 처리할 수도 있습니다. 다음은 과일이름을 key로, key에 해당하는 가격들을 value로 하는 Map을 생성하는 코드입니다.
val map2: Map<String, List<Int>> = fruits.groupBy({ fruit -> fruit.name }, { fruit -> fruit.price })
중복되지 않은 key를 가지고 Map을 생성할 때는 associateBy를 사용할 수 있습니다.
// Fruit 객체 내 중복되지 않는 id 필드가 필요합니다. val map: Map<Long, Fruit> = fruits.associateBy { fruit -> fruit.id } val map2: Map<Long, Long> = fruits .associateBy({ fruit -> fruit.id }, { fruit -> fruit.price })
Map에 대해서도 앞선 기능들을 대부분 사용할 수 있습니다. 다음은 groupBy로 생성한 map에 filter 를 사용한 코드입니다.
val map: Map<String, List<Fruit>> = fruits.groupBy { fruit -> fruit.name } .filter { (key, value) -> key == "사과" }
flatten
중첩되어 있는 컬렉션을 중첩 해제하기 위해 사용합니다. 즉, 평탄화 합니다. 다음은 List<List<>>를 List<> 형태로 평탄화 합니다.
// flatten val numbers = listOf(listOf(1,2,3), listOf(4, 5), listOf(6)) val result = numbers.flatten() println(result) // [1, 2, 3, 4, 5, 6]
flatMap
인자로 주어진 람다를 컬렉션에 적용하고 flatten 합니다.
val numbers = listOf(listOf(1, 2, 3), listOf(4, 5), listOf(6)) val result2 = numbers.flatMap { it.map { "number $it" } } println(result2) // [number 1, number 2, number 3, number 4, number 5, number 6]
평탄화 작업만 필요한 경우 flatten을 사용하고, 별도 처리가 필요한 경우 flatMap을 사용하면 됩니다.
감사합니다.
반응형'BackEnd > Kotlin' 카테고리의 다른 글
20강. 코틀린의 scope function (0) 2024.05.23 19강. 코틀린의 이모저모 (0) 2024.05.01 17강. 코틀린에서 람다를 다루는 방법 (1) 2024.04.07 16강. 코틀린에서 다양한 함수를 다루는 방법 (0) 2024.04.06 15강. 코틀린에서 배열과 컬렉션을 다루는 방법 (0) 2024.03.21