Kotlin Filtering Collections

Last Updated : 10 May, 2025

In Kotlin, working with collections like lists, sets, and maps is very common. One of the most useful tasks is filtering, that means selecting only the elements that meet a certain condition. Kotlin makes filtering easy and powerful using functions like filter(), filterNot(), filterIndexed(), and partition().

These filtering functions are based on something called a predicate. A predicate is just a fancy word for a function (usually a lambda) that takes a collection element and returns true or false. If it returns true, the element is included in the result; if it returns false, the element is left out.

Using filter() – The Basic Way to Filter

The most common function is filter(). When you use it with a list or set, it gives back a new list containing only the elements that match the condition. If you use it with a map, it returns a new map with only the key-value pairs that match.

Example:

Kotlin
fun main() {
    // declaring a list of elements
    val words = listOf("geek", "for", "geeks", "all", "geeks", "hello", "world")

    // filtering all words with length > 3
    val result = words.filter { it.length > 3 }
    println(result)

    //declaring a map of string to integers
    val map = mapOf("key25" to 20, "key45" to 40, "key55" to 50)

    //filtering the map with some predicates
    val filteredMap = map.filter { it.value > 30 }
    println(filteredMap)
}


Output: 

[geeks, geeks, hello, world]
{key45=40, key55=50}

These functions don’t change the original collection. They return a new one, and you can save that in a variable or keep chaining more functions to do more processing.


Filtering with Index: filterIndexed()

Sometimes, you may want to filter elements not just based on their value but also based on their position (index) in the list. For that, Kotlin provides filterIndexed(). It gives you both the index and the value, so you can filter based on either or both.

Example:

Kotlin
fun main() {
    val words = listOf("geek", "for", "geeks", "all", "world")
    val result = words.filterIndexed { index, value -> index % 2 != 0 }
    println(result)
}


Output:

[for, geeks, all, world]


Excluding Items: filterNot()

What if you want to keep all the elements except those that match a condition? That’s where filterNot() comes in. It’s like the opposite of filter().

Example:

Kotlin
fun main() {
    val words = listOf("geek", "geeks", "hello", "world")
    val result = words.filterNot { it.startsWith("h") }
    println(result)
}


Output: 

[geek, geeks, world]


Splitting Collections with partition()

There is another filtering function partition() which filters a collection by a predicate and separates all the elements, which don't match the predicate and put in a different list. Basically, it returns a pair of list: the first list containing the elements that match the predicate and the second list contains all the element from the original collection which don't match the predicate.

Example: 

Kotlin
fun main() {
    val words = listOf("geek", "geeks", "hello", "for", "world")
    val (matched, unmatched) = words.partition { it.length > 3 }
    println(matched)
    println(unmatched)
}


Output: 

[geeks, hello, world]
[geek, for]

Checking with Predicates: any(), none(), and all()

Besides filtering, Kotlin also gives you ways to test conditions on your collection using:

  • any() - returns true if at least one element matches the condition.
  • none() - returns true if no elements match.
  • all() - returns true if every element matches.

Note: If you call all() with a condition on an empty list, it will return true. This is called vacuous truth. It simply means that when there are no items to test, Kotlin assumes that “everything is fine.”

Example: 

Kotlin
fun main() {
    val words = listOf("geeks","for","geeeks","hello","world")

    //checking if atleast one word ends with s or not
    println("Any element matches? "+words.any { it.endsWith("s") })

    //checking if no word ends with a or not
    println("No element matches? "+words.none { it.endsWith("a") })

    println("All element match? "+words.all { it.endsWith("d") })
    //checking if all words end with d or not

    //when predicate is empty, it checks for emptiness
    println(words.any())
    println(words.none())

    //all function on an empty list
    println(emptyList<Int>().all { it > 5 })   // vacuous truth

    val empty = emptyList<String>()

    //any function on an empty list returns false
    println(empty.any())
    //none function on an empty list returns true
    println(empty.none())
}


Output: 

Any element matches? true
No element matches? true
All element match? false
true
false
true
false
true
Comment
Article Tags:

Explore