•
Kotlin에서는 필터링 조건을 조건문으로 정의하며 이는 컬렉션 요소를 받아 boolean 값을 반환하는 람다 함수이다.
•
true는 주어진 요소가 조건문에 맞음을 의미하고 false는 그 반대를 의미한다.
•
표준 라이브러리에는 컬렉션을 단일 호출로 필터링할 수 있는 확장 함수들이 포함되어 있다.
•
이 함수들은 원본 컬렉션을 변경하지 않으므로 가변 컬렉션과 읽기 전용 컬렉션 모두에 사용할 수 있다.
•
필터링 결과를 조작하려면 변수를 할당하거나 필터링 후 함수 체인을 연결해야 한다.
조건문으로 필터링
val numbers = listOf("one", "two", "three", "four")
val longerThan3 = numbers.filter { it.length > 3 }
println(longerThan3)
val numbersMap = mapOf("key1" to 1, "key2" to 2, "key3" to 3, "key11" to 11)
val filteredMap = numbersMap.filter { (key, value) -> key.endsWith("1") && value > 10}
println(filteredMap)
Kotlin
복사
•
기본 필터링 함수는 filter() 이다.
•
조건문과 함께 호출하면 filter() 는 해당 조건을 만족하는 컬렉션 요소를 반환한다.
•
List 와 Set 의 경우 결과 컬렉션은 List 이며 Map 의 경우에는 Map 이다.
val numbers = listOf("one", "two", "three", "four")
val filteredIdx = numbers.filterIndexed { index, s -> (index != 0) && (s.length < 5) }
println(filteredIdx)
Kotlin
복사
•
filter() 의 조건문은 요소의 값만 검사할 수 있다.
•
요소의 위치를 사용하여 필터링하려면 filterIndexed() 를 사용하라.
•
이 함수는 두 개의 인수(인덱스와 값)를 가진 조건문을 받는다.
val numbers = listOf("one", "two", "three", "four")
val filteredNot = numbers.filterNot { it.length <= 3 }
println(filteredNot)
Kotlin
복사
•
부정 조건으로 컬렉션을 필터링하려면 filterNot() 을 사용하라.
•
이는 조건문이 false를 반환하는 요소의 목록을 반환한다.
val numbers = listOf(null, 1, "two", 3.0, "four")
println("모든 문자열 요소 대문자:")
numbers.filterIsInstance<String>().forEach {
println(it.uppercase())
}
Kotlin
복사
•
filterIsInstance() 는 주어진 타입의 컬렉션 요소를 반환한다.
•
List<Any> 에서 호출하면 filterIsInstance<T>() 는 List<T> 를 반환하므로 해당 항목에 대해 T 타입의 함수를 호출할 수 있다.
val numbers = listOf(null, "one", "two", null)
numbers.filterNotNull().forEach {
println(it.length) // nullable 문자열에 대한 length는 사용 불가
}
Kotlin
복사
•
filterNotNull() 은 모든 non-nullable 요소를 반환한다.
•
List<T?> 에서 호출하면 filterNotNull() 은 List<T: Any> 를 반환하므로 요소를 non-nullable 객체로 처리할 수 있다.
분할
val numbers = listOf("one", "two", "three", "four")
val (match, rest) = numbers.partition { it.length > 3 }
println(match)
// [three, four]
println(rest)
// [one, two]
Kotlin
복사
•
partition() 은 조건문에 따라 컬렉션을 필터링하고 일치하지 않는 요소를 별도의 리스트로 유지한다.
•
따라서 반환 값은 두 개의 리스트로 구성된 Pair 이다.
•
첫 번째 리스트는 조건문과 일치하는 요소, 두 번째 리스트는 원본 컬렉션의 나머지 요소를 포함한다.
조건문 테스트
val numbers = listOf("one", "two", "three", "four")
println(numbers.any { it.endsWith("e") }) // true
println(numbers.none { it.endsWith("a") }) // true
println(numbers.all { it.endsWith("e") }) // false
println(emptyList<Int>().all { it > 5 }) // true
Kotlin
복사
•
any() 는 주어진 조건문에 맞는 요소가 하나라도 있으면 true를 반환한다.
•
none() 은 주어진 조건문에 맞는 요소가 하나도 없으면 true를 반환한다.
•
all() 은 모든 요소가 주어진 조건문에 맞으면 true를 반환한다. (빈 컬렉션에서도 true 반환)
val numbers = listOf("one", "two", "three", "four")
val empty = emptyList<String>()
println(numbers.any()) // true
println(empty.any()) // false
println(numbers.none()) // false
println(empty.none()) // true
Kotlin
복사
•
any() 와 none() 은 조건문 없이도 사용할 수 있다.
•
이 경우 단순히 컬렉션의 비어있음을 검사한다.
•
any() 는 요소가 있으면 true, 없으면 false를 반환하고 none() 은 그 반대이다.