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")
}