Kotlin聪明的投入了一个过滤器的第二个值

我试图写一个函数,映射一个字符串和诠释? 成对,然后在继续映射之前过滤该对中非空的第二个值。

我的代码如下所示:

val ids: List<String> = listOf("a", "b", "c") val ints: Map<String, Int?> = mapOf("a" to 1, "b" to 2, "c" to null) ids.map { id: String -> Pair(id, ints[id]) }.filter { pair -> pair.second != null}.map { pair: Pair<String, Int> -> func(id, pair.second) } 

问题是第二张地图有错误:

 Type inference failed: Cannot infer type parameter T in inline fun <T, R> kotlin.collections.Iterable<T>.map ( transform (T) -> R ): kotlin.collections.List<R> 

这看起来像是因为编译器不知道如何在我的filter后面将Iterable<Pair<String, Int?>>转换为Iterable<Pair<String, Int>> 。 我能做些什么来解决这个问题?

科特林的聪明演员通常不适用于方法界限之外。 但是,无论如何,有几种方法可以实现您的目标。

首先,您可以简单地告诉编译器,通过使用!!这个对的第二个值永远不会为空!! 运营商如此:

 ids.map { id: String -> Pair(id, ints[id]) } .filter { pair -> pair.second != null } .map { pair: Pair<String, Int?> -> func(pair.second!!) } 

其次,你可以颠倒filtermap的顺序,并应用!! 操作员较早:

 ids.filter { id: String -> ints[id] != null } .map { id: String -> id to ints[id]!! } //equivalent to Pair(id, ints[id]!!) .map { pair: Pair<String, Int> -> func(pair.second) } 

最后,你可以让它工作没有!! 运算符通过使用mapNotNull扩展方法在一个步骤中结合过滤和映射:

 ids.mapNotNull { id: String -> ints[id]?.let { id to it } } .map { pair: Pair<String, Int> -> func(pair.second) }