#kotlin #kotlin-flow
Вопрос:
В моем приложении у меня есть два потока данных, которые я хочу объединить в один, содержащий пару значений. Однако, когда Flow
A выдает новое значение, объединенное Flow
должно выдавать пару с нулевым значением, пока Flow
B не выдаст новое значение. Подумайте об этом так:
Flow A A --------------------------> B --------------------------> C ----->
Flow B 1 ---------> 2 ------------------------> 3 ----> 4 --------------> 5
Result A1 --------> A2 ------------> Bn ------> B3 ---> B4 ------> Cn --> C5
Где n
обозначает нулевое значение. Как я могу создать такое поведение? Может быть, есть функция расширения для этого в потоке, аналогичная zip
или около того?
Комментарии:
1. Возможно, поток B должен быть каналом?
Ответ №1:
Я не думаю, что есть простой способ сделать это с существующими операторами потока, но вы можете создать свой собственный, создав новый поток.
fun <A, B> combineWithNulls(flowA: Flow<A>, flowB: Flow<B>) = flow {
var previousB: B? = null
combine(flowA, flowB) { a, b -> a to b }.collect { (a, b) ->
if (b == previousB) {
emit(a to null)
} else {
previousB = b
emit(a to b)
}
}
}
Сначала мы используем оператор объединения для создания потока, который выдает новую пару каждый раз, когда какой-либо поток выдает элемент. Затем мы собираем объединенный поток и сравниваем значение flowB
со значением, которое хранится в переменной нашего нового потока. Если значения совпадают, мы выделяем null
. В противном случае мы выдаем реальное значение и обновляем сохраненное значение.