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.