Home > Net >  Is there findFirst with position in predicate in Kotlin
Is there findFirst with position in predicate in Kotlin

Time:06-27

I need to find first element in a list which fits predicate. But I need to check with it position in predicate.

    list.findXXX { index, item ->
        index > 19 && item.active
    }

Is there such a function?

CodePudding user response:

There is no such function yet, but you can easily write one yourself. It is not a lot of effort at all.

public inline fun <T> Iterable<T>.findIndexed(predicate: (Int, T) -> Boolean): T? {
    forEachIndexed { i, e -> if (predicate(i, e)) return e }
    return null
}

Alternatively, in general you can use a filterIndexed to first filter out the indexes that you want to exclude:

list
//  .asSequence() // if you want to be lazy
    .filterIndexed { i, _ -> i > 19 }
    .find { item -> item.active }

In fact, you could just put the entire condition in filterIndexed and use firstOrNull afterwards. It just may not read as nicely as find.

Of course in this specific case you can also just drop the first 20.

CodePudding user response:

I'm not familiar with such function, but I think this would work well for your example

list.drop(20).first{item -> item.isActive}

CodePudding user response:

You can make your custom extension function to achieve what you want

fun <T> List<T>.firstCustomOrNull(
    predicate: (index: Int, element: T) -> Boolean
): T? {
    forEachIndexed { index, element ->
        if (predicate(index, element)) return element
    }

    return null
}

now you can use that function the same way as .firstOrNull and you have access to the element and the index so you can use it in any custom way that you want:

list.firstCustomOrNull { index, element ->
    element.active && index > 19
}

This solution will work for any case and you can customize it more, but if you want to keep it simple you can just drop the first 20 element.

  • Related