У Kotlin есть array.indexOf, но я не могу понять, как это сделать array.indexOfBy {lambda}

У Kotlin есть array.indexOf(item) но я не могу понять, как это сделать array.indexOfBy { lambda } . Разве это не существует? Я могу find элемент, но я не могу получить его индекс в одно и то же время.

Я пропустил функцию в stdlib?

Я могу создать функцию с циклом, который chekcs элементы и возвращает, когда он находит цель. Как это:

 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 } 

Затем я попытался сделать его немного более функциональным, используя forEach :

 fun <T : Any> indexOfBy(items: Array<T>, predicate: (T) -> Boolean): Int { (items.indices).forEach { if (predicate(items[it])) { return it } } return -1 } 

Или я могу сделать что-то глупое, как это, что не очень показательно:

 val slowAndSilly = people.indexOf(people.find { it.name == "David" }) 

И то, что выглядит лучше всего, возможно, как функции расширения:

 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 

Есть ли более элегантный и идиоматический способ достичь этого?!? Я также не вижу такой функции для списков, коллекций и последовательностей.

(этот вопрос получен из комментария к другому сообщению )

Вы можете использовать indexOfFirst

 arrayOf(1, 2, 3).indexOfFirst { it == 2 } // returns 1 arrayOf(4, 5, 6).indexOfFirst { it < 3 } // returns -1 

Альтернативы, которые удобны в некоторых случаях:

 a.indices.first { a[it] == 2 } // throws NoSuchElementException if not found a.indices.find { a[it] == 2 } // null if not found 
Intereting Posts