filter, map
filter
와 map
은 컬렉션 함수의 기반이 되는 함수이다. 대부분의 컬렉션 연산을 이를 조합해서 표현할 수 있다.
filter
함수는 컬렉션을 이터레이션하면서 주어진 람다에 각 원소를 넘겨서 람다가 true
를 반환하는 원소만 모은다.
public inline fun <T> Iterable<T>.filter(predicate: (T) -> Boolean): List<T>
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>
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
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
val list = listOf(1, 2, 3, 4, 5)
println(list.any { isPrimeNumber(it) })
true
드모르간의 법칙(De Morgan’s Theorem)에 따라 어떤 조건에 대해 !all
의 결과와 그 조건의 부정에 대해 any
를 수행한 결과가 같고 어떤 조건에 대해 !any
를 수행한 결과와 그 조건의 부정에 대해 all
을 수행한 결과와 같다. 코드 가독성을 위해 all
과 any
앞에 !
를 붙이지 않는 것이 좋다
count
함수는 조건에 맞는 원소의 개수를 반환한다.
public inline fun <T> Iterable<T>.count(predicate: (T) -> Boolean): Int
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?
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>>
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>
val strings = listOf("abc", "def")
println(strings.flatMap { it.toList() })
[a, b, c, d, e, f]
만약 리스트의 리스트가 있는데 리스트를 딱히 변환할 내용이 없으면 flatten
함수를 사용하면 된다(위 그림의 flatten
부분 참고)