Contains() with predicate?


#1

There are times you just want to know if a certain element is in the collection, but don’t care what it is:

fun containsOdd(list: List<Int>) = list.firstOrNull { it % 2 == 1 } != null

But this looks kind of ugly with all the null business. I wish we had (in _Collections.kt) :

/**
 * Returns `true` if an element matching the [predicate] is found in the collection.
 */
public inline fun <T> Iterable<T>.contains(predicate: (T) -> Boolean): Boolean {
    for (element in this) if (predicate(element)) return true
    return false
}

(With similar for _Arrays.kt)

Then we could just do:

fun containsOdd(list: List<Int>) = list.contains { it % 2 == 1 }

Has this ever been proposed?


#2
inline fun <K, V> Iterator<out K, V>.any(
    predicate: (Entry<K, V>) -> Boolean
): Boolean

http://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/any.html


#3

Ah and there is any for Iterator too. Thank you.

(I rather wish there was any(element: T) as well for consistency. If they all used the same name they would have been easier to find.)


#4

but any asks is there any element that matches …
When you give a specific element, one the question is no longer is there any element that matches…


#5

Then what would happen if you called any on an Iterable<(T)->Boolean>? :wink:


#6

I don’t think it will improve consistency.

any(p: (T) -> Boolean): Boolean is paired with all(p: (T) -> Boolean): Boolean.
They work like the mathematical quantifiers “there exists (∃)” and “for all (∀)”, respectively.

They are the same as exists(predicate) and forall(predicate) in Scala.

You now, all(element: T) does not make much sense, because it will be true only if all of the elements of the collection is the same.