코틀린 언어 정리 4-6
Collection operations
Common operations( 일반적인 연산들 )
Grouping
같은 값의 element를 모아 하나로 줄입니다. 좀 더 구체적으로는, Array계열의 collection(List 포함)등에서 중복되는 요소들을 한개의 요소로 축약하여 Map으로 만드는 연산입니다. 대표적으로 groupBy와 groupingBy 연산이 있습니다. groupBy는 호출하면 바로 Map<K, List<T>>을 생성하고 groupingBy는 Grouping<T,K> 타입의 중간 단계의 객체를 생성합니다. 이 객체에서는 reduce, fold, aggregate등의 연산을 지원합니다. 이 연산들은 Map의 각 요소의 key, value(List<T>) 에서 value(List<T>)에 대해 적용됩니다.
Grouping연산은, Map을 생성하면서 축약된 요소(key)에 대응하는 각각의 값 들(value list)에 대해 누적 연산(reduce, fold, aggregate,...)등을 적용할 때 유용하게 사용할 수 있습니다.
groupBy ( keySelector, valueTransform ), groupingBy ( keySelector ): Grouping<>
Array or List 등에서의 reduce, fold
reduce
inline fun <S, T : S> Array<out T>.reduce(operation: (accumulator: S, element: T) -> S): S
element에 대한 임의의 연산 결과를 accumulator에 저장하여 리턴하고 다음 element에 대해 현재까지의 accumulator 값을 이용하여 동일한 연산을 다시 수행합니다. 이와 같은 과정을 모든 element에 대해 반복합니다.
accumulator의 초기 값은 첫번째 element입니다.
fold
inline fun <T, R> Array<out T>.fold(initial: R, operation: (accumulator: R, element: T) -> R): R
reduce와 동일한 기능이지만 처음 fold 연산을 시작할 때 accumulator의 초기값을 fold 함수 매개변수(initial)를 통해 지정할 수 있습니다.
groupBy, groupingBy
groupBy와 groupingBy를 비교하면, groupBy 연산은 후속 연산 없이 Map<K, List<T>>를 바로 생성하고 groupingBy 연산은 Grouping<T, K>를 생성한 후 이를 통해 Map의 value에 해당되는 List<T>에 aggregate, fold, reduce, eachCount등의 연산을 수행하여 Map<K, R>을 생성합니다. (K=key, T=element, R=key에 대응하는 List<T>에 대해 reduce, fold, aggregate 등과 같은 통합 연산을 적용한 결과)
groupingBy를 호출하여 Grouping<T,K>타입의 객체를 생성하면 현재 key에 Mapping되어 있는 value(Map의 각 요소에 대응하는 collection타입의 value)에 대해 누적 연산을 적용하여 새로운 Map에 저장할 수 있습니다.
Grouping<T, K>
groupingBy에서 리턴하는 Grouping<T, K>타입에서는 집계(누적)연산을 제공합니다. Array, List 등에서 제공되는 연산과 비슷하지만, Grouping<T, K>에서 제공되는 함수에는 첫번째 parameter에 key 가 추가되어 있습니다.
동작의 차이를 비교해 보면, Array, List등에서 제공되는 연산은 단지 리시버 객체(Array, List)에 연산이 적용된 후 단일 값이 리턴 되고, Grouping<T,K>에서 제공되는 연산은 groupBy에 의해 생성되는 Map 유형(Map<K, List<T>>)에서 List<T>에 해당되는, 즉 모든 key에 대응하는 value list에 집계 연산이 적용되어 최종적으로는 Map<K,T> 타입의(key, value Pair) Map이 생성됩니다.
aggregate
inline fun <T, K, R> Grouping<T, K>.aggregate(operation: (key: K, accumulator: R?, element: T, first: Boolean) -> R): Map<K, R>
reduce
inline fun <S, T : S, K> Grouping<T, K>.reduce(operation: (key: K, accumulator: S, element: T) -> S): Map<K, S>
fold
inline fun <T, K, R> Grouping<T, K>.fold(initialValueSelector: (key: K, element: T) -> R, operation: (key: K, accumulator: R, element: T) -> R): Map<K, R>
eachCount
Map의 key에 몇 개의 요소가 그룹화 되었는지 리턴합니다.
reduce, fold, aggregate 함수 선택 기준
reduce, fold, aggregate 함수는 큰 흐름에서 모두 동일한 연산을 수행 하지만 초기값 연산, accumulator 할당 시점 제어 연산과 관련하여 차이가 있습니다. 초기값 및 초기값이 발견되는 시점에 특별한 작업을 할 필요가 없을 경우 reduce, 그렇지 않을 경우 fold, 이에 추가로 accumulator의 할당까지 제어하려면 aggregate를 사용하면 됩니다.
예제
'코틀린( Kotlin )' 카테고리의 다른 글
코틀린 4-8 Collection operations - Retrieving Single Elements( 단일 요소 검색 ) (0) | 2020.04.13 |
---|---|
코틀린 4-7 Collection operations - Retrieving Collection Parts (0) | 2020.04.13 |
코틀린 4-5 Collection operations - Plus and Minus Operators (0) | 2020.04.12 |
코틀린 4-4 Collection operations - Filtering (0) | 2020.04.12 |
코틀린 4-3 Collection operations - Transformations (0) | 2020.04.11 |