Перемещение окна с помощью Kotlin Flow
Я пытаюсь создать движущееся окно данных с помощью Kotlin Flows. Это может быть достигнуто в RxKotlin с использованием буфера, но буфер - это не то же самое, что и с использованием потоков.
У RxKotlin есть оператор, который периодически собирает элементы, излучаемые Observable, в пакеты и выпускает эти пакеты, а не выделяет элементы по одному - buffer(count, skip)
Kotlin Flow имеет
buffer
но это просто запускает сборщик в отдельной сопрограмме - буфере
Есть ли в Flows существующий оператор, который может этого добиться?
1 ответ
Я думаю, что то, что вы ищете, недоступно в библиотеке Kotlinx Coroutines, но есть открытая проблема .
В этом комментарии также есть возможная реализация , которую я также включу сюда:
fun <T> Flow<T>.windowed(size: Int, step: Int): Flow<List<T>> = flow {
// check that size and step are > 0
val queue = ArrayDeque<T>(size)
val toSkip = max(step - size, 0) < if sbd would like to skip some elements before getting another window, by serving step greater than size, then why not?
val toRemove = min(step, size)
var skipped = 0
collect { element ->
if(queue.size < size && skipped == toSkip) {
queue.add(element)
}
else if (queue.size < size && skipped < toSkip) {
skipped++
}
if(queue.size == size) {
emit(queue.toList())
repeat(toRemove) { queue.remove() }
skipped = 0
}
}
}