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 的超类型。这意味着您不能将reduceList&lt;B&gt; 转换为List&lt;A&gt;

在“其他语言”中,您可以在归约时指定一个“标识元素”,并且您可能也想这样做。在 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

如何限制 kotlin 协程的最大并发性

Java 8流限制功能是否有任何等效的Kotlin函数[重复]

你应该学Kotlin吗

Kotlin用高阶函数处理集合数据

Java vs Kotlin 应该使用Kotlin进行Android开发吗