🚗 · Predicates

3 min read · Updated on by

Read on for an introduction to the most important functions for predicates: all, any, none, isEmpty, isNotEmpty, ifEmpty, contains, containsAll, and their variants.

Predicate functions

all, any, none


//sampleStart
inline fun <T> Iterable<T>.all(predicate: (T) -> Boolean): Boolean
inline fun <T> Iterable<T>.any(predicate: (T) -> Boolean): Boolean
//sampleEnd

The all method accepts a predicate and returns true if every element satisfies the predicate, and false otherwise. The some method has the same input, but returns true if at least one element satisfies the predicate, and false otherwise.

Example


//sampleStart
fun main() {
    val list = listOf(1, 2, 3, 4)
    list.all { it % 2 == 0 }.also(::println) // false
    list.any { it % 2 == 0 }.also(::println) // true
}
//sampleEnd

There are also variations of any and none that take no arguments, and return true if the collection has at least one element and no elements, respectively.

Example


//sampleStart
fun main() {
    val list = listOf(1)
    list.any().also(::println) // true
    list.none().also(::println) // false
    emptyList<Int>().none().also(::println) // true
}
//sampleEnd

isEmpty, isNotEmpty, ifEmpty


//sampleStart
fun isEmpty(): Boolean
inline fun <T> Collection<T>.isNotEmpty(): Boolean
inline fun <C : Collection<*>, R> C.ifEmpty(
    defaultValue: () -> R
): R where C : R
//sampleEnd

The isEmpty method is not an extension, but defined directly on the Collection interface. Predictably, it returns true if the collection contains no elements. For Listnone is an alias for isEmpty. The opposite of isEmpty is isNotEmpty. There is also isNullOrEmpty, which is defined on a nullable receiver:


//sampleStart
inline fun <T> Collection<T>?.isNullOrEmpty(): Boolean
//sampleEnd

Of interest is the ifEmpty method, which allows us to substitute a different Collection if the receiver is empty. Notice that the type of the return value is always the type of what is returned by defaultValue, which can be a super-type of the receiver.

Example


//sampleStart
fun main() {
    val list1 = emptyList<Int>() // List<Int>
    val list2 = listOf(1, 2, 3) // List<Int>

    list1.ifEmpty { listOf(4, 5.2, 3) }.also(::println) // List<Number> { 4, 5.2, 3 }
    list2.ifEmpty { listOf(4, 5.2, 3) }.also(::println) // List<Number> { 1, 2, 3 }
}
//sampleEnd

contains, containsAll


//sampleStart
operator fun <T> Iterable<T>.contains(element: T): Boolean
inline fun <T> Collection<T>.containsAll(
    elements: Collection<T>
): Boolean
//sampleEnd

We already know contains from the chapter on operators. It can be invoked using the in keyword. The containsAll expands on this functionality by returning true only if the receiver contains all the elements of the argument, and false otherwise. Naturally, it is not an operator.

Example


//sampleStart
fun main() {
    val list = listOf(1, 2, 3)

    list.contains(2).also(::println) // true
    println(2 in list) // true

    // listOf(1, 2) in list // Won't compile. Equivalent to list.contains(listOf(1, 2))
    list.containsAll(listOf(1, 2)).also(::println) // true
}
//sampleEnd

Leave a Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.

The Kotlin Primer