https://kotlinlang.org logo
#flow
Title
# flow
s

Simon Lin

03/23/2021, 1:57 AM
Can I receive most recently two value when a new value emit? for example: emit: 1, 2, 3, 4, 5, 6 downstream receive: [initValue, 1] [1, 2] [2, 3] [3, 4] [4, 5] [5, 6]
e

ephemient

03/23/2021, 3:44 AM
nothing built in, but writing your own operator is easy:
Copy code
fun <T> Flow<T>.zipWithNext(initValue: T): Flow<Pair<T, T>> = flow {
    var lastValue = initValue
    collect {
        emit(lastValue to it)
        lastValue = it
    }
}

flowOf(1, 2, 3, 4, 5, 6).zipWithNext(0).toList() ==
    listOf(0 to 1, 1 to 2, 2 to 3, 3 to 4, 4 to 5, 5 to 6)
👀 1
could even write something more general like
Copy code
fun <T> Flow<T>.windowed(
    size: Int,
    step: Int = 1,
    partialWindows: Boolean = false
): Flow<List<T>> {
    require(size > 0 && step > 0)
    return flow {
        val window = ArrayDeque<T>(size)
        var count = 0
        collect {
            if (window.size >= size) window.removeFirst()
            window.add(it)
            if (window.size == size && count == 0) emit(window.toList())
            count = (count + 1) % step
        }
        if (partialWindows) {
            while (window.size > 1) {
                window.removeFirst()
                if (count == 0) emit(window.toList())
                count = (count + 1) % step
        	}
        }
    }
}

flowOf(1, 2, 3, 4, 5, 6).onStart { emit(0) }.windowed(2).toList() ==
    listOf(listOf(0, 1), listOf(1, 2), listOf(2, 3), listOf(3, 4), listOf(4, 5), listOf(5, 6))
n

Natsuki(开元米粉实力代购)

03/23/2021, 11:27 AM
the more general format is built-in
fold
Copy code
listOf(1, 2, 3).asFlow().fold(0) { prev, ele ->
        println(prev to ele)
        ele
    }
e

ephemient

03/23/2021, 7:04 PM
if you're working on
List<>
then you already have
.zipWithNext()
and
.windowed()
in stdlib 🙂
🙌 1
3 Views