Kotlin reduce 有限制吗?
Posted
技术标签:
【中文标题】Kotlin reduce 有限制吗?【英文标题】:Kotlin reduce has limitations? 【发布时间】:2021-07-17 17:20:52 【问题描述】:我想使用 reduce 方法实现相同的以下代码。我知道这在其他语言中是可能的,但我不知道如何在 Kotlin 中实现它
class A
class B (val a: A?)
fun test(listOfBs: List<B>): List<A>
return listOfBs.filter it.a != null .map it.a!!
// TODO return listOfBs.reduce ???
【问题讨论】:
【参考方案1】:您可以使用mapNotNull
from the Kotlin Standard Library,而不是先调用filter
,然后再调用map
。这个函数结合了两者,你可以避开Hold My Beer operator(!!
)。
例子:
fun test(listOfBs: List<B>): List<A> =
listOfBs.mapNotNull it.a
【讨论】:
【参考方案2】:Kotlin 中的reduce
不适合这个。它是这样声明的:
inline fun <S, T : S> Iterable<T>.reduce(
operation: (acc: S, T) -> S
): S
注意它只能返回一个S
,它是元素类型T
的超类型。这意味着您不能将reduce
和List<B>
转换为List<A>
。
在“其他语言”中,您可以在归约时指定一个“标识元素”,并且您可能也想这样做。在 Kotlin 中,您可以使用 fold
:
fun test(listOfBs: List<B>): List<A> =
listOfBs.fold(emptyList()) acc, b ->
if (b.a != null)
acc + listOf(b.a) // this is very bad code, it creates a bunch of unnecessary lists
else
acc
当然,“仅当不为空时才映射”是一件很常见的事情,它已经内置在 Kotlin 标准库中 - mapNotNull
:
fun test(listOfBs: List<B>): List<A> =
listOfBs.mapNotNull it.a
【讨论】:
【参考方案3】:你可以看看 reduce
在 Kotlin 标准库中是如何实现的:
https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/reduce.html
【讨论】:
以上是关于Kotlin reduce 有限制吗?的主要内容,如果未能解决你的问题,请参考以下文章
Kotlin Coroutines 选择 Dispatcher