Home > other >  Get the second element in the array that fulfills some condition
Get the second element in the array that fulfills some condition

Time:09-12

Working on Android/Kotlin app, I'm having trouble finding indices of second and third element in the array that fulfills some condition. Since I know there are 4 elements in the array that would return true, i can use indexOfFirst() and indexOfLast(), but that way, I get only the first and the fourth indices.

val array: Array<String>

val firstOne = array.indexOfFirst(::func)
val lastOne = array.indexOfLast(::func)

fun func(element: String): Boolean{
   return element=="a" }

I tried using filterIndexed() but that returns a new list, and only values are saved, but not indices of the elements in there, which I need

CodePudding user response:

You can use withIndex to get the items with their indices and then filter that.

val elements: List<IndexedValue<String>> = array.withIndex().filter { (_, value) -> func(value) }

If you only need indices:

val indices = array.withIndex().filter { (_, value) -> func(value) }.map { it.index }

Or if you want to assign each of these to a variable instead of getting a list:

val iterator = array.asSequence().withIndex()
    .filter { (_, value) -> func(value) }
    .iterator()

val (firstIndex, firstValue) = iterator.next()
val (secondIndex, secondValue) = iterator.next()
val (thirdIndex, thirdValue) = iterator.next()
val (fourthIndex, fourthValue) = iterator.next()

If you only need indices:

val iterator = array.asSequence().withIndex()
    .filter { (_, value) -> func(value) }
    .map { it.index }
    .iterator()

val first = iterator.next()
val second = iterator.next()
val third = iterator.next()
val fourth = iterator.next()

CodePudding user response:

You can create an extension function for Iterable like this:

inline fun <T> Iterable<T>.findAndSkip(skip: Int = 0, predicate: (T) -> Boolean): T? {
    var index = 0
    for (element in this) {
        if (predicate(element) && index   == skip)
            return element
    }

    return null
}

and use it like this:

fun main() {
    val list = listOf("Masoud", "Saeed", "Mahmoud", "Ramin", "Mohammad", "Reza", "Mohsen")
    val value1 = list.findAndSkip(skip = 0, predicate = ::predicate)
    val value2 = list.findAndSkip(skip = 1, predicate = ::predicate)
    val value3 = list.findAndSkip(skip = 2, predicate = ::predicate)
    val value4 = list.findAndSkip(skip = 3, predicate = ::predicate)
    val value5 = list.findAndSkip(skip = 4, predicate = ::predicate)

    println(value1) // Masoud
    println(value2) // Mahmoud 
    println(value3) // Mohammad 
    println(value4) // Mohsen
    println(value5) // null
}

fun predicate(value: String): Boolean {
    return value.startsWith("M")
}

I hope it will help you.

  • Related