在地图上按值谓词查找的惯用方式

时间:2019-12-27 06:52:24

标签: kotlin

搜索地图并找到与谓词value匹配的第一个键的最佳方法是什么?否则为null?我的以下代码对于kotlin标准来说太冗长了。请帮忙。

fun  <K, V> find(map : Map<K, V?>, predicate: (V?) -> Boolean): K? {
    var key : K? = null
    map.forEach { it ->
        if(predicate(it.value)) {
            key = it.key
            return@forEach
        }
    }
    return key
}

4 个答案:

答案 0 :(得分:3)

map.entries.firstOrNull { predicate(it.value) }?.key

entries用于使Map迭代,并且是“免费的”(因为它不需要遍历地图)。当然,它可以启用Map本身(而不仅仅是firstOrNull)上缺少的所有集合扩展功能。

(您也可以将firstOrNull替换为find;在这里它们是等效的。)

答案 1 :(得分:1)

您不需要var key,您可以立即返回找到的密钥,最后返回return null

在传递给forEach的lambda中,您可以使用参数解构来访问键和值,而无需使用it

fun  <K, V> find(map : Map<K, V?>, predicate: (V?) -> Boolean): K? {
    map.forEach { (key, value) ->
        if (predicate(value)) {
            return key
        }
    }
    return null
}

此外,您可以将map参数转换为接收器,使其成为可在地图实例上调用的扩展函数:

fun <K, V> Map<K, V>.findKeyByValue(predicate: (V) -> Boolean): K? {
    forEach { (key, value) ->
        if (predicate(value)) {
            return key
        }
    }
    return null
}
val result = myMap.findKeyByValue { it > 0 }

答案 2 :(得分:0)

结合使用filterfirstOrNull

val firstKey = map.keys.filter { it == 1 }.firstOrNull()

要使其变得懒惰,请将其转换为以下序列:

val firstKey = map.keys.asSequence().filter { it == 1 }.firstOrNull()

答案 3 :(得分:0)

您可以使用过滤器搜索地图并找到第一个键

例如

var arr = mutableMapOf<Any, Any>()
        arr.put("1", "dax1")
        arr.put("2", "dax2")
        arr.put("3", "dax3")
        arr.put("4", "dax4")

        val key = arr.filter {
            it.value.equals("dax5")
        }.keys
        if (key.isNotEmpty()) {
            Log.e("key", key.elementAt(0).toString())
        } else {
            Log.e("key", "Key not found")
        }

希望这对您有帮助