我有三个对象(例如A,B,C),要获取CI,需要B,要获取A,我需要B。在屏幕中,我需要同时显示A的属性和C的属性。我可以获取所有必要的数据,因为我使用的是不带onComplete的flatMap,因此不会执行toList()。这是我的代码。
对于列表中的每个a,我需要获取c,并且需要返回ResultMode类型的列表,其中包括a和c的属性。
override fun methodICall(): LiveData<MutableList<ResultModel>> {
return mySdk
.getAllA() //Returns Flowable<List<A>>
.flatMap { Flowable.fromIterable(it) }
.flatMap { helperMethod(it) }
.toList() // Does not get executed as flatMap isnt completed
.toFlowable()
.onErrorReturn { Collections.emptyList() }
.subscribeOn(Schedulers.io())
.to { LiveDataReactiveStreams.fromPublisher(it) }
}
private fun helperMethod(a:A): Flowable<ResultModel> {
return mySdk
.getB(a.propertyOne!!) // Returns Single<B>
.flatMap { mySdk.getC(it.property!!) } // get C returns Single<C>
.map {
ResultModel(name= a.name,
date = c.date.toString(),
message = it.messageId!!
)
}.toFlowable()
}
注意:我今天早些时候问过类似的问题,但并不需要多次使用平面图。您可以在此链接中查看我的解决方案
RxJava - Mapping a result of list to another list
我的努力(可能错了) 这是我转换第一种方法的工作(对于第二种方法,我只是将其删除为Flowable并返回单一方法),但是还有很长的路要走,我认为我走错了路。
override fun methodICall(): LiveData<MutableList<ResultModel>> {
return mySdk
.getAllA()
.concatMapSingle { Flowable.fromIterable(it)
.map { helperMethod(it) }
.toList()
}
.onErrorReturn { Collections.emptyList() }
.subscribeOn(Schedulers.io())
.to { LiveDataReactiveStreams.fromPublisher(it) // here it is single. I think it is because two maps are applied both to helperMethod itself and inside helper method to result model}
}
答案 0 :(得分:1)
编辑:我找到了另一个解决方案
override fun methodICall(): LiveData<MutableList<ResultModel>> {
return mySdk
.getAllA()
.concatMapSingle {
Flowable.fromIterable(it)
.flatMap { a ->
mySdk.getB(a.propertyOfA!!)
.flatMap { b -> chatbotSdk.getC(b.propertyOfB!!) }
.map { it ->
ResultModel(name = a.name,
message = it.body!!)
}.toFlowable()
} .toList() }
.onErrorReturn { Collections.emptyList() }
.subscribeOn(Schedulers.io())
.to { LiveDataReactiveStreams.fromPublisher(it) }
}
原始解决方案
这是我的解决方案,但我认为该解决方案确实很杂乱,可以进行很多改进。
data class AtoBDTO(var name: String, var b: Flowable<B>) // I wanted to map one object to more than one so I created this. Probably there is a way to do it with rx functions.
data class BtoCDTO(var name: String, var c: Flowable<C>)
override fun methodICall(): LiveData<MutableList<ResultModel>> {
return mySdk
.getAllA() // Returns Flowable<List<A>>
.concatMapSingle {
Flowable.fromIterable(it)
.map { AtoBDTO(it.name!!,
mySdk.getB(it.propertyOfA!!).toFlowable()) } //getB returns Single B
.toList()
}
.concatMapSingle {
Flowable.fromIterable(it)
.map {
BtoCDTO(it.name,
it.b.concatMapSingle { mySdk.getC(it.propertyOfB!!) }) // getC returns Single C
}
.toList()
}
.concatMapSingle {
Flowable.fromIterable(it)
.map {
ResultModel(name = it.name,
message = it.c.blockingFirst().body!!) // I use blocking first because otherwise I can't get rid of flowable
}.toList()
}
.onErrorReturn { Collections.emptyList() }
.subscribeOn(Schedulers.io())
.to { LiveDataReactiveStreams.fromPublisher(it) }
}
答案 1 :(得分:1)
似乎没有必要不断地解构和重建列表。假设没有:
override fun methodICall(): LiveData<MutableList<ResultModel>> {
return mySdk
.getAllA() // Returns Flowable<List<A>>
.flatMapIterable(it)
.concatMapSingle( item => {
mySdk.getB(item.propertyOfA!!)
.flatMap( bItem => mySdk.getC( bItem.propertyOfB!! ) )
.map( ResultModel( name=item.name, message=it.body!! ) )
})
.toList()
.onErrorReturn { Collections.emptyList() }
.subscribeOn(Schedulers.io())
.to { LiveDataReactiveStreams.fromPublisher(it) }
}
由于concatMapSingle()
运算符知道每个项目,因此在构造ResultModel
时可以知道其名称。现在,您不再需要如此频繁地撕碎东西。