- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我有一些自定义字段,每个字段都有一个可以使用 BehaviorSubject<Value>
检索的值.显示哪些字段是基于我从 API 获得的,所以最后我有 n 个 BehaviorSubject<Value>
秒。我想将这些值组合成一个 Observable<List<Value>>
其中列表包含来自这些字段的最新值(顺序无关紧要)。然而,问题是这些字段并非同时可用,因为它们是在 UI 加载时创建的,因此我无法使用 Observable.combineLatest
与主题列表。
我目前所做的是创建了以下变量:
private val values = BehaviorSubject.create<Pair<Int, Value>>()
我使用这个主题来订阅该领域的所有主题,但首先将主题与其位置进行映射,然后将其配对。
fieldSubject.map {
Pair(position, value)
}.subscribe(values)
然后我想做的是根据它们在对中的位置对值进行分组并得到 Observable<List<Value>>
其中列表包含每个位置的最新值。但是,在使用 groupBy
对它们进行分组后,我不知道如何进行:
values.groupBy {
it.first
}
这导致 Observable<GroupedObservable<Pair, Value>>>
.最后这就是我认为我应该去 Observable<List<Value>>
的方式,但我不知道从这里可以做什么。
最佳答案
groupBy
在这里对我似乎没有帮助。
累积值通常使用 scan
完成,在这里您可以使用如下转换:
values.scanWith({ arrayOfNulls<Value>(N) }) { acc, (index, value) ->
acc.copyOf().apply {
set(index, value)
}
}
.map { it.filterNotNull() }
如果没有 copyOf()
,您可能会逃脱,但我想我过去遇到过累加器函数不纯的问题。
顺便说一句,你可以写position to value
而不是 Pair(position, value)
.
此外,您可以使用 merge
得到一个Observable<Pair<Int, Value>>
而不是创建 BehaviorSubject
并手动将其订阅到所有字段:
Observable.mergeArray(
fieldX.map { 0 to it },
fieldY.map { 1 to it },
fieldZ.map { 2 to it }
// ...
)
总的来说,你可以有一个函数来为你做这一切:
inline fun <reified T : Any> accumulateLatest(vararg sources: Observable<out T>): Observable<List<T>> {
return Observable.merge(sources.mapIndexed { index, observable ->
observable.map { index to it }
})
.scanWith({ arrayOfNulls<T>(sources.size) }) { acc, (index, value) ->
acc.copyOf().apply {
set(index, value)
}
}
.map { it.filterNotNull() }
}
然后调用:
accumulateLatest(fieldX, fieldY, fieldZ)
.subscribe {
println("Latest list: $it")
}
关于android - 按需组合嵌套 Observable 的最新值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52451992/
我是一名优秀的程序员,十分优秀!