简体   繁体   English

Kotlin:filterNotNull 用于 Map 中的值<k,v?></k,v?>

[英]Kotlin: filterNotNull for values in a Map<K,V?>

Here's the Kotlin code I'd like to write (with extra type annotations for clarity):这是我想写的 Kotlin 代码(为了清楚起见,带有额外的类型注释):

fun test(alpha: String, beta: String, gamma: String? = null, delta: String? = null) {
    val r1: Map<String, String?> =
        hashMapOf(
            "alpha" to alpha,
            "beta" to beta,
            "gamma" to gamma,
            "delta" to delta
        )
    val r2: Map<String, String> = r1.filterValues { it != null }
    callSomeFunction(r2)  // expects a parameter of type Map<String, String>
}

Unfortunately, r1.filterValues { it != null } gives me back a Map<String, String?> , not a Map<String, String> .不幸的是, r1.filterValues { it != null }给了我一个Map<String, String?> ,而不是一个Map<String, String> I understand why this is;我明白为什么会这样; it's the same reason that listOf(1, null).filter { it != null } has a different type from listOf(1, null).filterNotNull() .这与listOf(1, null).filter { it != null }listOf(1, null).filterNotNull()具有不同类型的原因相同。 However, I still need to solve my problem!但是,我仍然需要解决我的问题!

Is there an idiomatic way to "filterValuesNotNull" from a Map ?是否有从Map中“filterValuesNotNull”的惯用方法?

Or, stepping up a level, is there some other idiomatic way to say "give me a Map of the following arguments, but skip those whose values are null"?或者,提高一个级别,是否有其他惯用的方式说“给我一个Map的以下 arguments,但跳过那些值为空的”? I could resort to this , but I don't want to:我可以诉诸这个,但我不想:

fun test(alpha: String, beta: String, gamma: String? = null, delta: String? = null) {
    var r1: MutableMap<String, String> = mutableMapOf(
        "alpha" to alpha,
        "beta" to beta
    )
    if (gamma != null) {
        r1["gamma"] = gamma
    }
    if (delta != null) {
        r1["delta"] = delta
    }
    callSomeFunction(r1)  // expects a parameter of type Map<String, String>
}

Here's 2 ways to do it, although whether either is idiomatic, I do not know.这里有两种方法,虽然我不知道是否是惯用的。

@Suppress("UNCHECKED_CAST)
fun filterNotNullUnchecked(map: Map<String, String?>): Map<String, String> =
  map.filterValues { it != null } as Map<String, String>

EDIT: As @Tenfour04 pointed out, this isn't unsafe, just unchecked because of type erasure, and adding a Suppress("UNCHECKED_CAST) annotation makes the warning go away.编辑:正如@Tenfour04 所指出的,这不是不安全的,只是因为类型擦除而未选中,并且添加Suppress("UNCHECKED_CAST)注释会使警告 go 消失。

fun filterNotNullUgly(map: Map<String, String?>): Map<String, String> {
  val map2 = HashMap<String, String>()
  for ((k, v) in map) if (v != null) map2[k] = v
  return map2
}

The functions that in my opinion should be in the stdlib:我认为应该在标准库中的功能:

fun <K,V: Any> Map<K,V?>.filterNotNullValuesTo(destination: MutableMap<K,V>): Map<K, V> {
    for ((key, value) in entries) if (value != null) destination[key] = value
    return destination
}

fun <K,V: Any> Map<K,V?>.filterNotNullValues(): Map<K,V> = filterNotNullValuesTo(mutableMapOf())

hm, I suppose, it can be decided on that way嗯,我想,可以这样决定

val newMap: Map<String, String> = r1.mapNotNull { (key, value) ->
    value?.let { key to it }
}.toMap()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM