조용한 담장

코틀린(Kotlin) Collections : plus and minus Operators, Grouping 본문

kotlin

코틀린(Kotlin) Collections : plus and minus Operators, Grouping

iosroid 2020. 3. 27. 14:54

kotlin

코틀린의 collection 의 plus and minus Operators 와 Grouping 에 대해 살펴보자.

원문 https://kotlinlang.org/docs/reference/collection-plus-minus.htmlhttps://kotlinlang.org/docs/reference/collection-grouping.html 을 보며 정리.

plus and minus Operators

plus (+) 와 minus (-) 연산자들의 결과로 read-only collection 이 생성된다.

minus 는 두번째 피연산자의 element 들을 원본 collection 에서 제외한 결과를 리턴한다.

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

val plusList = numbers + "five"
val minusList1 = numbers - listOf("three", "four")
val minusList2 = numbers - listOf("ten", "three", "four")
val minusList3 = numbers - listOf("one", "two", "three", "four")
println(plusList)
println(minusList1)
println(minusList2)
println(minusList3)

// output:
// [one, two, three, four, five]
// [one, two]
// [one, two]
// []

augmented assignment operators plusAssign (+=) 와 minusAssign (-=) 도 collections 에 사용이 가능하다.

하지만 read-only collection 에 사용하면 plus, minus 연산자를 사용한 결과를 다시 같은 변수에 할당하는 동작이 일어나게 된다.

그러므로 이 연산자들은 var read-only collection 에만 동작이 가능하다.

mutable collections 에 사용하면 val 이면 그 collection 을 수정한다.

자세한 동작은 Collection Write Operations 에서 살펴보자.

val numbers = mutableListOf("one", "two", "three", "four")
numbers += listOf("five", "six")
println(numbers)
numbers -= listOf("one", "two")
println(numbers)

// output:
// [one, two, three, four, five, six]
// [three, four, five, six]

Grouping

groupBy() 람다 함수를 인자로 받아 Map 으로 collection 의 element 를 grouping 하여 리턴한다.

각 key 는 람다 함수의 결과값이 되고, value 는 그 결과가 만들어지는 element 들로 구성된 List 가 된다.

inline fun <T, K> Iterable<T>.groupBy(
   keySelector: (T) -> K
): Map<K, List<T>>

두번째 argument 를 사용하는 방법으로 keySelector 람다 함수의 결과 값으로 key 를 결정하고

valueTransform 의 람다 함수의 결과값들을 element로 가진 List 를 value 로 정한다.

inline fun <T, K, V> Iterable<T>.groupBy(
   keySelector: (T) -> K,
   valueTransform: (T) -> V
): Map<K, List<V>>
val numbers = listOf("one", "two", "three", "four", "five")

println(numbers.groupBy { it.first().toUpperCase() })
println(numbers.groupBy(keySelector = { it.first() }, valueTransform = { it.toUpperCase() }))

// output:
// {O=[one], T=[two, three], F=[four, five]}
// {o=[ONE], t=[TWO, THREE], f=[FOUR, FIVE]}

it.first().toUpperCase() 의 각 결과 값인 O, T, T, F, F 를 grouping 한 O, T, F 가 key 가 된다.

각 key 로 grouping 된 element 들이 리스트에 포함되어 value 가 된다.

["one"], ["two", "three",], ["four", "five"]

groupingBy() 를 사용하면 grouping 한 후 모든 group 에 어떤 동작을 한번에 적용할 수 있다.

inline fun <T, K> Iterable<T>.groupingBy(
   crossinline keySelector: (T) -> K
): Grouping<T, K>

이 함수는 Grouping type 의 인스턴스를 리턴하고 이를 통해 모든 group 에 동작을 적용할 수 있게 된다.

interface Grouping<T, out K>

Grouping 은 아래의 동작을 지원한다.

  • eachCount() 각 그룹의 element 의 개수를 리턴한다.

  • fold()reduce() 는 각 그룹을 구분된 collection 으로써 fold and reduce 동작을 수행하고 결과를 리턴한다.

  • aggregate() 는 각 그룹의 모든 element 에 주어진 동작을 연속적으로 적용하고 그 최종 결과를 리턴한다. fold and reduce 외의 다른 동작들을 구현 하고자 할때 이 함수를 이용할 수 있다.

val numbers = listOf("one", "two", "three", "four", "five", "six")
println(numbers.groupingBy { it.first() }.eachCount())

// output:
// {o=1, t=2, f=2, s=1}


Comments