Kotlin 콜렉션 정리 프로젝트1 - groupingBy

달의꿈·2020년 7월 4일
3

Kotlin Collection에는 groupingBy라는 확장함수가 있습니다. 배열이나 콜렉션에 대해 keySelector을 이용해서 그룹화와 폴드 연산을 하고, 그룹화된 소스를 반환합니다(먼소리야🤔)..

먼말인지 감이 안오니 원형을 보져!!!

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

crossinlineinline함수를 이용하는 과정에 생길 수 있는 문제점을 해결하기 위한 수식어로, 람다함수를 다른 개체에 대입할 때 return을 무시해주는 함수입니다. 🙄??????????? 일단 여기서 요지는 아니므로 inlinecrossinline가볍게 무시해줍시다!

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으로 되어 있어서 더 편리하게 이용할수도...

References

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

profile
Everything to me

0개의 댓글