【问题标题】:How can I write the transformation in a cleaner way如何以更简洁的方式编写转换
【发布时间】:2020-05-27 17:19:22
【问题描述】:

我有一个方法,它需要一个对象列表(小部件)——它包含一些属性(标题)和嵌套列表(组件)。我想将列表展平为一个列表,并使用以下代码:

@SuppressLint("CheckResult")
    fun flatten(fatList: Single<List<Widget>>) {
        val flatList: MutableList<IUiData> = mutableListOf()

        fatList.map {
            Observable.fromIterable(it).map { widget ->
                if (widget.header.isNotEmpty()) {
                    flatList.add(ProductHeaderUi(widget.header))
                }
                widget.componentList.map { component ->
                    when (component.type) {
                        TILE_TEXT -> {
                            flatList.add(HeaderUi(component))
                        }
                        TILE_IMAGE -> {
                            flatList.add(ImageTileUi(component))
                        }
                        TILE_FOOTER -> {
                            flatList.add(FooterUi(component))
                        }
                        UNKNOWN -> {
                            //Do Nothing 
                        }
                    }
                }
            }
        }
    }

我打算从这个方法返回一个 List 的 Single: Single&lt;MutableList&lt;IUiData&gt;&gt;,这个目的现在可以达到,但我正在寻找一种更清洁的方法

【问题讨论】:

  • 将Single 转换为MutableList 并没有真正意义,因为您必须等待数据产生。你可以把它变成Single&lt;MutableList&lt;IUiData&gt;&gt;。这就是你想要的吗?
  • 是的,我的错,应该是Single&lt;MutableList&lt;IUiData&gt;&gt;
  • 我已经更新了问题,谢谢指出!

标签: kotlin rx-java rx-java2


【解决方案1】:

您无意中同时使用了 Rx 的 Observable map 和 Kotlin 的 Iterable map。它们用于将一种类型转换为另一种类型,而不是用于迭代。

您还在最外层的 map 函数中嵌套了一个不必要的 Observable 可迭代对象。

您只需要映射 Single 的输出。在 map 函数中,您迭代(不是 map)原始 List 以提取 MutableList 所需的数据。

我是 Rx 新手,没有检查这个,对于任何语法错误非常抱歉。

fun flatten(fatList: Single<List<Widget>>): Single<MutableList<IUData>> = fatList.map { widgetList ->
    val flatList: MutableList<IUiData> = mutableListOf()
    for (widget in widgetList) {
        if (widget.header.isNotEmpty()) {
            flatList.add(ProductHeaderUi(widget.header))
        }
        for (component in widget.componentList) { 
            when (component.type) {
                TILE_TEXT -> flatList.add(HeaderUi(component))
                TILE_IMAGE -> flatList.add(ImageTileUi(component))
                TILE_FOOTER -> flatList.add(FooterUi(component))
                // Else do nothing
            }
        }
    }
    flatList
}

但是为了与典型的 Rx 链接语法保持一致,我会将其设为扩展函数,所以我必须像这样在第一行。然后你可以把它放在 Rx 调用链的中间:

fun Single<List<Widget>>.flatten(): Single<MutableList<IUData>> = map { widgetList ->

您还可以通过使用 Kotlin 的 flatMap 以更简洁、更实用但效率更低的方式执行此操作:

fun Single<List<Widget>>.flatten(): Single<MutableList<IUData>> = map {
    it.flatMap { widget ->
        listOfNotNull(widget.header.takeIf(Header::isNotEmpty)?.let(::ProductHeaderUi))
        +
        widget.componentList.mapNotNull { component ->            
           when (component.type) {
                TILE_TEXT -> HeaderUi(component)
                TILE_IMAGE -> ImageTileUi(component)
                TILE_FOOTER -> FooterUi(component)
                else -> null
            }
        }.toMutableList()
}

...Headerwidget.header 使用的任何类型。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-11-17
    • 2019-01-27
    • 1970-01-01
    • 1970-01-01
    • 2015-07-16
    • 1970-01-01
    • 2012-09-12
    • 1970-01-01
    相关资源
    最近更新 更多