从数组扩展函数 kotlin 获取给定元素的索引

Get index of given element from array extension function kotlin

我想更多地了解 Kotlin 扩展函数,并且正在尝试为 List 实现扩展函数,以通过传递位置值(如果有意义的话)来获取元素的索引。

我有:

fun List<String>.getItemPositionByName(item: String): Int {
    this.forEachIndexed { index, it ->
        if (it == item)
            return index
    }
    return 0
}

虽然这很好用,但我也需要同样的东西用于 Int。 对于我的问题,有没有办法将其组合成一个扩展函数而不是两个单独的扩展函数?我承认这不是很多代码,复制也无妨,但出于兴趣和供将来参考。

我知道这个问题 那里的回答是——至少我是这么理解的——“不太像这样,但我真的不需要它来打字,但是” just" 用于 String 和 Int。

Kotlin 在一定程度上支持 C++ 人所说的专业化。它适用于像您正在使用的非常基本的类型,因此您所要求的绝对是可能的。

我们可以声明以下声明。当然,您只需复制代码即可。

public fun List<String>.getItemPositionByName(item: String) = ...
public fun List<Int>.getItemPositionByName(item: String) = ...

如果您不喜欢重复代码,惯用的方法是使用文件私有函数并简单地委托给私有函数。

private fun <T> getItemImpl(list: List<T>, item: T): Int {
    list.forEachIndexed { index, it ->
        if (it == item)
            return index
    }
    return -1
}

public fun List<String>.getItemPositionByName(item: String) = getItemImpl(this, item)
public fun List<Int>.getItemPositionByName(item: Int) = getItemImpl(this, item)

这限制了 getItemImpl,它对您所在的当前文件完全通用,而 IntString 专业化在其他任何地方都是公开可用的。

尝试在任何非 List<Int>List<String> 类型的列表上调用 getItemPositionByName 将失败并出现类型错误。

科特林游乐场Link:https://pl.kotl.in/NvIRXwmpU

以防万一你不知道,你正在实现的方法已经存在于标准库中 (https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/index-of.html)

Kotlin 标准库已经有一个函数可以做到这一点:indexOf()

val one = listOf("a", "b", "c").indexOf("b")
check(one == 1)

一种选择是查看 implementation of that function

还有 first() 函数,如果您想编写自己的通用版本,可以使用它:

fun <T> List<T>.getItemPositionByName(item: T) = withIndex()
    .first { (_, value) -> item == value }
    .index

fun main(args: Array<String>) {
    val one = listOf("a", "b", "c").getItemPositionByName("b")
    check(one == 1)
}

或者,重写您的原始版本以使用泛型:

fun <T> List<T>.getItemPositionByName(item: T): Int {
    this.forEachIndexed { index, it ->
        if (it == item)
            return index
    }
    return 0
}