[英]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.