Kotlin Collection에는 groupingBy
라는 확장함수가 있습니다. 배열이나 콜렉션에 대해 keySelector
을 이용해서 그룹화와 폴드 연산을 하고, 그룹화된 소스를 반환합니다(먼소리야🤔)..
먼말인지 감이 안오니 원형을 보져!!!
inline fun <T, K> Array<out T>.groupingBy( crossinline keySelector: (T) -> K ): Grouping<T, K>
※ crossinline
은 inline
함수를 이용하는 과정에 생길 수 있는 문제점을 해결하기 위한 수식어로, 람다함수를 다른 개체에 대입할 때 return
을 무시해주는 함수입니다. 🙄??????????? 일단 여기서 요지는 아니므로 inline
과 crossinline
은 가볍게 무시해줍시다!
※ out
키워드는 읽기전용임을 의미합니다. 이 역시 가볍게 무시해줍시다!
우리에게 필요한 부분만 골라보면
//주의!! 이거는 코틀린에서 제공하는 groupingBy의 원형이 아닙니다!! fun <T, K> Array<T>.groupingBy( keySelector: (T) -> K ): Grouping<T, K>
이죠! keySelector
라는 함수를 이용해서 어떻게 그루핑을 할지 정해주는 것이 일단 첫번째입니다.
간단한 예를 몇 개 들어보죠!😎
"someText".groupingBy(Char::toLowerCase)
문자 someText를 모두 소문자화하여 문자하나하나로 나눈 후에
('s', 'o', 'm', 'e', 't', 'e', 'x', 't'),
소문자 하나하나를 key로 묶는 방법입니다. (T:Char, K:Char)
그러면 보기 좋게 순서쌍 (T, K)
로 나타내면 위는
('s', 's'), ('o', 'o'), ('m', 'm'), ('e', 'e'),
('t', 'T'), ('e', 'e'), ('x', 'x'), ('t', 't')
로 묶이게 되겠지요.
대문자 T가 key로서는 소문자로 저장된 것을 알 수 있습니다.🤩
그럼 두 번째 예!
listOf("a", "bc", "de").groupingBy{it.length} //람다식을 이용해서 밖으로 빼주었습니다!
list의 문자들을 문자 길이를 key로 하여 묶는 방법입니다. (T:String, K:Int)
즉, 여기서는 2라는 key를 가진 것 "bc", "de"가 한묶음,
1이라는 key를 가진 "a"가 한 묶음이 되도록 묶이겠지요.
우리의 목적이 groupingBy
를 이용하여 그루핑된 것의 개수를 세고 싶다면 이와 연결된 함수 하나를 더 사용해야 합니다.
바로 eachCount
함수!
fun <T, K> Grouping<T, K>.eachCount(): Map<K, Int>
해당 key
를 가진 것의 개수를 Map
으로 반환해주면서, 이를 이용해 다양한 문제를 해결할 수 있게 됩니다. 예를 보겠습니다.
val result = "someText".groupingBy(Char::toLowerCase).eachCount() println(result) //{s=1, o=1, m=1, e=2, t=2, x=1}
이렇게 개수가 쫙 계산되어 나오기 때문에, map
의 확장함수를 이용해서 다양한 필터링을 추가로 할 수 있겠죠! 😅🤣🤣
하나의 예를 더 보면
// list 내에서 유일한 단어의 길이를 가진 문자 개수 반환환 val numberOfUniqueLengthWord = listOf("a", "bc", "de", "e", "f", "ggf").groupingBy{ it.length }.eachCount().count{it.value == 1} println(numberOfUniqueLengthWord)
을 들 수 있겠습니다~~!!
자매함수 groupBy
의 함수의 형태를 소개해드리면서, 한번 groupingBy
함수와 어떤 차이가 있는지, 위 코드를 조금 더 효율적으로 생각할 순 없을지 생각해보는 것도 좋을 것 같네요!!!😀😀 사실 위 코드들은 연습을 위한 문제라 돌고도는 느낌이 강해ㅅ...
inline fun <T, K> Array<out T>.groupBy( keySelector: (T) -> K ): Map<K, List<T>> //반환 형태가 Map으로 되어 있어서 더 편리하게 이용할수도...
groupingBy 레퍼런스 : https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/grouping-by.html
groupBy 레퍼런스 :
https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/group-by.html