filter, map

filtermap은 컬렉션 함수의 기반이 되는 함수이다. 대부분의 컬렉션 연산을 이를 조합해서 표현할 수 있다.

filter 함수는 컬렉션을 이터레이션하면서 주어진 람다에 각 원소를 넘겨서 람다가 true를 반환하는 원소만 모은다.

public inline fun <T> Iterable<T>.filter(predicate: (T) -> Boolean): List<T>
filter
val list = listOf(1, 2, 3, 4, 5)
println(list.filter { it % 2 == 0 })

[2, 4]

map 함수는 주어진 람다를 컬렉션의 각 원소에 적용한 결과를 모아서 새 컬렉션을 만든다.

public inline fun <T, R> Iterable<T>.map(transform: (T) -> R): List<R>
map
val list = listOf(1, 2, 3, 4, 5)
println(list.map { it * it })

[1, 4, 9, 16, 25]

all, any, count, found

all 함수는 컬렉션의 모든 원소가 어떤 조건을 만족하는 지 판단한다.

public inline fun <T> Iterable<T>.all(predicate: (T) -> Boolean): Boolean
all
val list = listOf(1, 2, 3, 4, 5)
println(list.all { isPrimeNumber(it) })

false

any 함수는 컬렉션에 어떤 조건을 만족하는 원소가 있는지 판단한다.

public inline fun <T> Iterable<T>.any(predicate: (T) -> Boolean): Boolean
any
val list = listOf(1, 2, 3, 4, 5)
println(list.any { isPrimeNumber(it) })

true

드모르간의 법칙(De Morgan’s Theorem)에 따라 어떤 조건에 대해 !all의 결과와 그 조건의 부정에 대해 any를 수행한 결과가 같고 어떤 조건에 대해 !any를 수행한 결과와 그 조건의 부정에 대해 all을 수행한 결과와 같다. 코드 가독성을 위해 allany 앞에 !를 붙이지 않는 것이 좋다

count 함수는 조건에 맞는 원소의 개수를 반환한다.

public inline fun <T> Iterable<T>.count(predicate: (T) -> Boolean): Int
count
val list = listOf(1, 2, 3, 4, 5)
println(list.count { it % 2 == 1 })

3

count 함수를 사용하지 않고 filter + size를 사용하여 조건을 만족하는 원소의 개수를 구할 수도 있다.

list.filter { it % 2 == 1 }.size

그러나 이 방법은 중간 컬렉션(filter의 결과 컬렉션)을 만들기 때문에 비효율적이다.

find 함수는 조건을 만족하는 첫 번째 원소를 반환한다.

public inline fun <T> Iterable<T>.find(predicate: (T) -> Boolean): T?
find
val list = listOf(1, 2, 3, 4, 5)
println(list.find { it % 2 == 0 })

2

groupBy

groupBy는 리스트를 여러 그룹으로 이뤄진 맵으로 변경한다. groupBy의 결과는 원소를 구분하는 특성(아래 예제는 age)이 key이고, 키 값의 그룹 리스트(Person 객체의 모임)가 value이다.

public inline fun <T, K> Iterable<T>.groupBy(keySelector: (T) -> K): Map<K, List<T>>
groupBy
val list = listOf(
    Person("Alice", 31),
    Person("Bob", 29),
    Person("Carol", 31)
)
println(list.groupBy { it.age })

{31=[Person(name=Alice, age=31), Person(name=Carol, age=31)], 29=[Person(name=Bob, age=29)]}

각 그룹은 리스트이기 때문에 위 예제의 groupBy의 결과 타입은 Map<Int, List>이다.

flatMap, flatten

flatMap 함수는 먼저 인자로 주어진 람다를 컬렉션의 모든 객체에 적용하고(map) 람다를 적용한 결과 얻어지는 여러 리스트를 한 리스트로 모은다(flatten).

public inline fun <T, R> Iterable<T>.flatMap(transform: (T) -> Iterable<R>): List<R>
flatMap (map -> flatten)
val strings = listOf("abc", "def")
println(strings.flatMap { it.toList() })

[a, b, c, d, e, f]

만약 리스트의 리스트가 있는데 리스트를 딱히 변환할 내용이 없으면 flatten 함수를 사용하면 된다(위 그림의 flatten 부분 참고)


© 2021. All rights reserved.

Powered by Hydejack v9.1.6