💡 Kotlin

[Kotlin] Collection 함수 - (1) 원소 변환 및 필터, 특정원소 검색

콩드로이드 2023. 1. 12. 18:26

컬렉션의 원소 타입을 변환하거나 필터링 하는 과정은 

코딩테스트에서 빈번하게 사용되더라구요 

꼭 익혀두도록 해야겠어요 :) 

 

Collection에 확장함수는 정말 너무나도 많아요.. 

공식문서에 스크롤이 이를 증명합니다..

 

어떻게 나눠야 하나 많이 고민했는데 

우선 

 

1️⃣ 원소 변환 및 필터, 특정원소 검색

2️⃣ 수학적 개념

3️⃣ index 관련

4️⃣ 형식변환5️⃣ 값 반환 및 정렬

 

순으로 정리해볼까 해요 :) 이유는 제맘입니다..🫢 바뀔수도 있어요 ,, 

 


원소 변환

Map

Collection<T> 타입을 Collection<R> 타입으로 변환

공식문서엔 아래와 같이 설명되어있어요

 

Returns a list containing the results of applying the given transform function to each element in the original array.

 

즉, 원래의 배열에서 각 원소마다 지정한 변환을 적용해서 return 한다고 생각하면 됩니다 

 

사실 예를 보면 굉장히 쉬운데 막상 손에 익어 적용하기 까진 꽤 걸리더라구여

val list = listOf(1,2,3)
println(list.map{it * it})

[1, 4, 9]가 출력되겠죠 :) 

 


MapIndexed

Map과 크게 다르진 않아요, index까지 제공해준다는 것에 차이가 있습니다 

 

Returns a list containing the results of applying the given transform function to each element and its index in the original array.

 

예시가 딱히 생각나는 게 없는데

var list = listOf(1,2,3,4,5,6,7,8,9,10)
list.mapIndexed{index,i -> 
	println("$index : $i")
}

이런 형태로 사용되거나, 혹은 짝수번째의 index들만 가져온다거나.. 할 때 쓰일 수 있겠죵 😀

 


MapNotNull

Returns a list containing only the non-null results of applying the given transform function to each element in the original array.

 

원래의 배열에서 각 원소마다 지정한 변환을 적용해서 null이 아닌 값들만 return 한다고 생각 :)

 

마찬가지로 MapIndexed도 MapIndexedNotNull을 사용하면 null이 아닌 값들만 return 합니다

 

 


원소 필터링

map과 비슷한 형식의 부분은 8282 지나가볼게요

filter 

지정된 필터와 일치하는 값들만 리턴

Returns a list containing only elements matching the given predicate.

inline fun <T> Array<out T>.filter(
    predicate: (T) -> Boolean
): List<T>

inline fun <K, V> Map<out K, V>.filter(
    predicate: (Entry<K, V>) -> Boolean
): Map<K, V>

Array와 Map의 경우로만 확장함수를 알아보자면, 아래와 같습니다 

형태 그대로를 반환해준다고 생각하면 됩니다 

 

예를 들어, 대문자인 경우만 출력하고 싶다면 아래와 같이 사용하면 되겠져 :)

val list = listOf('A', 'B', 'c', 'D', 'e','f')
println(list.filter { it.isUpperCase() }.joinToString("") )

 


filterNot

filterNot은 filter와 반대로, 지정된 필터에 포함되지 않는 값들만 리턴합니다

그리고 null이 아닌 값들만 리턴받기 위해서 filterNotNull도 존재해요 

 

 


filterIndexed

filter에 Index만 추가한 함수입니다 

 


filterIsInstance

조금 특이한 형태의 함수에요  원형부터 살펴보자면, 

fun <reified R> Array<*>.filterIsInstance(): List<R>
fun <reified R> Iterable<*>.filterIsInstance(): List<R>

지정한 타입(R)에 맞는 원소만 걸러내는 함수입니다 

 

 

예를 살펴보면, 

open class Animal(val name: String) {
    override fun toString(): String {
        return name
    }
}
class Dog(name: String): Animal(name)
class Cat(name: String): Animal(name)

val animals: List<Animal> = listOf(Cat("Scratchy"), Dog("Poochie"))
val cats = animals.filterIsInstance<Cat>()

println(cats) // [Scratchy]

filterIsInstance<R>에 'Cat' 타입이 들어갔으므로, animals에서 Cat타입인 Scratchy만 반환합니다 

만약, 지정 타입에 해당하는 값이 없으면 []이 출력됩니다 

 

val cats = animals.filterIsInstance(Cat::class.java)

<R> 뿐만 아니라 R::class.java의 형태도 가능하겠쥬

 


특정 원소  검색

find

Returns the first element matching the given predicate, or null if no such element was found.

 

조건에 매치되는 첫번째 원소만 반환하고 없으면 null을 반환합니다 

⚠️ filter와 헷갈리지 않게 조심..!  filter는 체에 거른다고 생각하고, find는 하나만 검색한다고 생각

 

val list = listOf('A', 'B', 'c', 'D', 'e','f')
println(list.find { it.isLowerCase()})

여기선  소문자 c,e,f 중 가장 첫번째 원소인 c가 출력됩니다 :)

 

 

findLast

조건에 매치되는 마지막 원소만 반환하고 없으면 null을 반환합니다 

 


first

너무나도 직관적인 이름처럼, 첫번째 원소만 반환합니다 

 

firstNotNullOf

null이 아닌 첫번째 원소를 반환하며, 반환할 값이 null이라면 NoSuchElementException 이 발생됩니다

 val list  = emptyList<Int>()
 list.firstNotNullOf { println(it) }

 

firstNotNullOrNull

firstNotNullOf와 같은 기능을 하지만, null인 경우 에러발생 없이 null 그대로 반환합니다 

 

 

 

last, lastNotNullOf, lastNotNullOrNull은 first값이 아닌 Last값을 가져온다고 생각하면 됩니다 

따로 적진 않을게요 :) 


 

elementAtOrElse

해당 인덱스의 원소를 반환하거나, 범위를 벗어난 인덱스라면 defaultValue를 반환

val list = listOf(1, 2, 3)
println(list.elementAtOrElse(0) { 42 }) // 1
println(list.elementAtOrElse(2) { 42 }) // 3
println(list.elementAtOrElse(3) { 42 }) // 42

val emptyList = emptyList<Int>()
println(emptyList.elementAtOrElse(0) { "no int" }) // no int

 

 


elementAtOrNull

해당 인덱스의 원소를 반환하거나, 범위를 벗어난 인덱스라면 null 반환

val list = listOf(1, 2, 3)
println(list.elementAtOrNull(0)) // 1
println(list.elementAtOrNull(2)) // 3
println(list.elementAtOrNull(3)) // null

val emptyList = emptyList<Int>()
println(emptyList.elementAtOrNull(0)) // null

 


singleOrNull

단일 원소라면 원소를 반환하고, 비어있는 배열이거나 둘 이상의 원소면 null 반환

 

val list  = listOf(9,2)
println(list.singleOrNull())

// null 반환

var list = listOf(1)
println(list.singleOrNull())

// 1 반환

 


정말.. 길었습니다 ㅎㅎ

이제 이게 1편이라니..!

남은 Collection 함수들도 많으니 잘 정리해볼게요..

화이팅입니다 >_< 

'💡 Kotlin' 카테고리의 다른 글

[kotlin] forEach(람다식)의 return break, continue처럼 사용하기  (0) 2024.01.05
[Activity] LaunchMode  (0) 2023.06.15
[Kotlin] mutable Collection  (0) 2023.01.08
[Kotlin] Collection (List, Set, Map)  (0) 2023.01.03
[kotlin] Pair  (0) 2023.01.02