如何从列表中收集地图,其中排除/跳过空值?
此代码不会跳过空值:
val map = listOf(Pair("a", 1), Pair("b", null), Pair("c", 3), Pair("d", null))
.associateBy({ it.first }, { it.second })
println(map)
Run Code Online (Sandbox Code Playgroud)
解决方案.但收集到可变的地图:
val map2 = listOf(Pair("a", 1), Pair("b", null), Pair("c", 3), Pair("d", null))
.mapNotNull {
if (it.second != null) it else null
}.toMap()
println(map2)
Run Code Online (Sandbox Code Playgroud)
那么有更方便的方法吗?我也希望得到Map<String, Int>类型,而不是Map<String, Int?>
小智 11
从 Kotlin 1.6 开始,还有一个稳定的buildMap函数,可用于编写高性能且不牺牲可读性的自定义辅助函数:
fun <T, K : Any, V : Any> Iterable<T>.associateByNotNull(
keySelector: (T) -> K?,
valueTransform: (T) -> V?,
): Map<K, V> = buildMap {
for (item in this@associateByNotNull) {
val key = keySelector(item) ?: continue
val value = valueTransform(item) ?: continue
this[key] = value
}
}
Run Code Online (Sandbox Code Playgroud)
请注意,将其编写为“低级”for 循环可以消除创建中间集合的需要。
你想过滤掉null值,那么你应该使用filter方法:
val map = listOf(Pair("a", 1), Pair("b", null), Pair("c", 3), Pair("d", null))
.filter { it.second != null }
.toMap()
println(map)
Run Code Online (Sandbox Code Playgroud)
实际上,对pwolaq的回答略有改变,保证第二项不可为空:
val map = listOf(Pair("a", 1), Pair("b", null), Pair("c", 3), Pair("d", null))
.mapNotNull { p -> p.second?.let { Pair(p.first, it) } }
.toMap()
println(map)
Run Code Online (Sandbox Code Playgroud)
这将给你一个Map<String, Int>,因为mapNotNull忽略了映射到的任何东西null,并且使用let安全调用操作符,?.如果它的receiver(p.second)是,则返回null null.
这基本上就是你在问题中所说的,缩短了let.
你是什么意思"收集到可变地图"?
| 归档时间: |
|
| 查看次数: |
3043 次 |
| 最近记录: |