Kotlin ma array.indexOf(item)
, ale nie mogę się dowiedzieć, jak to zrobić array.indexOfBy { lambda }
. Czy to nie istnieje? Mogę find
przedmiot, ale nie mogę uzyskać jego indeksu w tym samym czasie.Kotlin ma array.indexOf, ale nie mogę się dowiedzieć, jak to zrobić array.indexOfBy {lambda}
Czy brakuje mi funkcji w stdlib?
Mogę utworzyć funkcję z pętlą, która chekcs elementy i zwraca, gdy znajdzie cel. Tak:
fun <T : Any> indexOfBy(items: Array<T>, predicate: (T) -> Boolean): Int {
for (i in items.indices) { // or (i in 0..items.size-1)
if (predicate(items[i])) {
return i
}
}
return -1
}
Potem starałem się zrobić to trochę bardziej funkcjonalną forEach
:
fun <T : Any> indexOfBy(items: Array<T>, predicate: (T) -> Boolean): Int {
(items.indices).forEach {
if (predicate(items[it])) {
return it
}
}
return -1
}
Albo mogę zrobić coś głupiego jak ten, który nie jest bardzo wydajnych:
val slowAndSilly = people.indexOf(people.find { it.name == "David" })
A to, co wygląda najlepiej, może być funkcją rozszerzającą:
fun <T: Any> Array<T>.indexOfBy(predicate: (T)->Boolean): Int =
this.withIndex().find { predicate(it.value) }?.index ?: -1
fun <T: Any> Collection<T>.indexOfBy(predicate: (T)->Boolean): Int =
this.withIndex().find { predicate(it.value) }?.index ?: -1
fun <T: Any> Sequence<T>.indexOfBy(predicate: (T)->Boolean): Int =
this.withIndex().find { predicate(it.value) }?.index ?: -1
Czy istnieje bardziej elegancki i idiomatyczny sposób na osiągnięcie tego?!? Również nie widzę takiej funkcji dla list, kolekcji ani sekwencji.
(kwestia ta pochodzi od comment on another post)