我正在尝试通过一系列过滤器和映射调用来转换列表。过滤逻辑再次用于映射调用中,我想避免重复调用。我认为代码总结得很好:
fun main(args: Array<String>) {
multipleCalls()
wontCompile()
}
fun multipleCalls(){
val arr = intArrayOf(1,2,3)
val list = arr.filter{
it.heavyLogic() != null
}.map{
it.heavyLogic() //heavyLogic() called again
}
print(list)
}
fun wontCompile(){
val arr = intArrayOf(1,2,3)
val list = arr.map{
val str = it.heavyLogic()
if(str == null) continue //break and continue are only allowed inside a loop
else str
}
print(list)
}
地图内是否有等效的中断/继续功能,可以修复wontCompile()
?
我意识到我也可以让map
返回null
,从而使list
的类型为List<String?>
-然后将filter
乘以null
。但这仍然使列表重复两次。
答案 0 :(得分:2)
您可以使用mapNotNull。
inline fun <T, R : Any> Array<out T>.mapNotNull(
transform: (T) -> R?
): List<R> (source)
我意识到我也可以让map返回null,从而列出 键入列表-然后按null进行过滤。但这仍然是反复的 列表两次。
通过使用mapNotNull
,列表仅需要迭代一次,在此期间将忽略空项目。
/**
* Applies the given [transform] function to each element in the original collection
* and appends only the non-null results to the given [destination].
*/
public inline fun <T, R : Any, C : MutableCollection<in R>> Iterable<T>.mapNotNullTo(destination: C, transform: (T) -> R?): C {
forEach { element -> transform(element)?.let { destination.add(it) } }
return destination
}
在您的代码中,您可以执行以下操作:
val list = arr.mapNotNull{
it.heavyLogic()
}
您还可以查看有关filterNotNull的信息。