Kotlin有array.indexOf,但我无法弄清楚怎么做array.indexOfBy {lambda}

时间:2016-03-02 22:10:54

标签: kotlin

Kotlin有array.indexOf(item),但我无法弄清楚如何做array.indexOfBy { lambda }。它不存在吗?我可以find一个项目,但我不能同时得到它的索引。

我错过了stdlib中的函数吗?

我可以创建一个带有循环的函数,该循环可以解析项目并在找到目标时返回。像这样:

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

有没有更优雅和惯用的方法来实现这一目标?!?对于列表,集合和序列,我也没有看到这样的函数。

(此问题来自comment on another post

2 个答案:

答案 0 :(得分:16)

您可以使用indexOfFirst

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

答案 1 :(得分:-2)

在某些情况下方便的替代方案:

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