Filtering
The standard library contains a group of extension functions that let you filter collections in a single call. These functions leave the original collection unchanged, so they are available for both mutable and read-only collections. To operate the filtering result, you should assign it to a variable or chain the functions after filtering.
The basic filtering function is . When called with a predicate, filter()
returns the collection elements that match it. For both List
and Set
, the resulting collection is a List
, for Map
it’s a Map
as well.
To filter collections by negative conditions, use filterNot()
. It returns a list of elements for which the predicate yields false
.
fun main() {
//sampleStart
val numbers = listOf("one", "two", "three", "four")
val filteredIdx = numbers.filterIndexed { index, s -> (index != 0) && (s.length < 5) }
val filteredNot = numbers.filterNot { it.length <= 3 }
println(filteredIdx)
println(filteredNot)
There are also functions that narrow the element type by filtering elements of a given type:
- returns collection elements of a given type. Being called on a
List<Any>
,filterIsInstance<T>()
returns aList<T>
, thus allowing you to call functions of theT
type on its items.
filterNotNull()
returns all non-null elements. Being called on aList<T?>
,filterNotNull()
returns aList<T: Any>
, thus allowing you to treat the elements as non-null objects.
fun main() {
//sampleStart
val numbers = listOf(null, "one", "two", null)
numbers.filterNotNull().forEach {
println(it.length) // length is unavailable for nullable Strings
}
//sampleEnd
}
Finally, there are functions that simply test a predicate against collection elements:
- returns
true
if at least one element matches the given predicate. all()
returnstrue
if all elements match the given predicate. Note thatall()
returnstrue
when called with any valid predicate on an empty collection. Such behavior is known in logic as .
fun main() {
//sampleStart
val numbers = listOf("one", "two", "three", "four")
println(numbers.any { it.endsWith("e") })
println(numbers.none { it.endsWith("a") })
println(numbers.all { it.endsWith("e") })
println(emptyList<Int>().all { it > 5 }) // vacuous truth
//sampleEnd
}
any()
and none()
can also be used without a predicate: in this case they just check the collection emptiness. any()
returns true
if there are elements and false
if there aren’t; none()
does the opposite.