Nuke Olaf - Log Store
[Kotlin] 표준 라이브러리 - kotlin.collections/ map, filter 본문
Kotlin Standard Library 는 collection 에서 유용하게 사용할 수 있는 기능들을 제공한다.
오늘은 그중에서 map 과 filter 에 대해 공부해보았다.
1. map
kotlin-stdlib/kotlin.collections/map
map 은 원소를 원하는 형태로 변환한 List 를 반환한다.
Returns a list containing the results of applying the given transform function to each element in the original array.
val numbers = listOf(1, 2, 3)
println(numbers.map { it * it }) // [1, 4, 9]
* map 응용
data class Movie(
val title: String, // 영화 제목
val actor: String // 영화 출연진
)
이런 형태의 영화 데이터를 저장하는 data class 가 있다고 생각해보자.
그런데, Movie 데이터의 title 프로퍼티가 html 형식으로 들어와서 String 형식으로 바꿔줘야 한다.
또한, 출연진 String 이
"김아무개|김수한무" 이런 형식으로 되어있어서
"출연진 : 김아무개, 김수한무" 이런 형식으로 바꿔주려고 한다.
map 을 사용하지 않는 기존 방식이라면, 아래와 같이 for 문을 사용할 것이다..
fun processMovie(movies: List<Movie>): List<Movie> {
for (movie in movies) {
movie.apply {
title = Html.fromHtml(title, Html.FROM_HTML_MODE_LEGACY).toString()
actor = actor.split("|")
.joinToString(
prefix = "출연진 : ",
separator = ", "
)
}
}
return movies
}
하지만, map 을 사용하면 아래와 같이 표현할 수 있다.
fun processMovie(movies: List<Movie>): List<Movie> {
return movies.map {
it.copy(
title = Html.fromHtml(title, Html.FROM_HTML_MODE_LEGACY).toString()
actor = actor.split("|")
.joinToString(
prefix = "출연진 : ",
separator = ", "
)
)
}
}
2. filter
kotlin-stdlib/kotlin.collections/filter
filter 는 predicate형태의 람다식을 인자로 받아 조건에 따라 collection의 원소를 filtering 한다.
predicate 는 "서술" 이라는 뜻으로, 여기서는 collection 의 원소를 인자로 받아 서술된 조건을 만족하는지 참/거짓 여부를 Boolean 으로 리턴하는 람다를 뜻한다.
Returns a list containing only elements matching the given predicate(lambda functions that take a collection element and return a boolean value). 참고
val numbers: List<Int> = listOf(1, 2, 3, 4, 5, 6, 7)
val evenNumbers = numbers.filter { it % 2 == 0 }
val notMultiplesOf3 = numbers.filterNot { number -> number % 3 == 0 }
println(evenNumbers) // [2, 4, 6]
println(notMultiplesOf3) // [1, 2, 4, 5, 7]
* filter 응용
data class Person(
val name: String,
val age: Int
)
나이가 30살 이상인 사람의 이름을 출력하는 코드를 작성해보자
val people = listOf(Person("olaf", 24), Person("oshy", 26), Person("void", 30))
val overThirty = people.filter { it.age > 29 }
println(overThirty) // [Person(name=void, age=30)]
나이가 가장 많은 사람의 이름을 출력해야한다면 두 가지 방식으로 코드를 작성할 수 있다.
val people = listOf(Person("olaf", 24), Person("oshy", 26), Person("void", 30))
// filter 내부에서 maxBy 사용 (비 권장)
val oldest = people.filter { it.age == people.maxBy{Person::age}!!.age }
// filter 외부에서 maxBy 사용
val maxAge = people.maxBy{Person::age}!!.age
val oldest = people.filter { it.age == maxAge }
println(oldest) // [Person(name=void, age=30)]
Person::age 는 it.age 와 같은 뜻이다
filter 내부에서 maxBy 를 사용한 코드의 경우 filter 를 돌면서 max 를 구하기 위해 또 내부적으로 for 문을 돌게 되기 때문에 매우 비효율적인 코드이다.
코드량을 무작정 줄이기보다는 반복이 중첩되지 않는지 내부적인 동작에 대해 고려하여 작성하는것이 좋다.
참고 사이트 >>>
'Language > [Kotlin]' 카테고리의 다른 글
[Kotlin] 코루틴(Coroutine)이란? - CoCurrency 와 비동기 프로그래밍 (2) | 2020.07.07 |
---|---|
[Kotlin] data class 란? (0) | 2020.05.10 |
[Kotlin] 안드로이드 - ArrayList 와 mutableListOf 의 차이 (0) | 2020.04.10 |
[Kotlin] 코틀린 범위 지정 함수 let, with, run, apply, also (0) | 2020.03.31 |