org.mattshoe.shoebox.kernl.runtime.ext.FlowExtensions.kt Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of Kernl.Runtime Show documentation
Show all versions of Kernl.Runtime Show documentation
Kernl: A Kotlin Symbol Processing (KSP) library for automatic repository generation.
The newest version!
package org.mattshoe.shoebox.kernl.runtime.ext
import kotlinx.coroutines.channels.ProducerScope
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.channelFlow
import kotlinx.coroutines.flow.conflate
import kotlinx.coroutines.flow.flow
import kotlin.experimental.ExperimentalTypeInference
/**
* Emits distinct elements from the source flow based on a provided predicate, selectively filtering out consecutive
* duplicates.
*
* The `selectivelyDistinct` extension function allows you to filter a flow such that only elements that differ based
* on a given predicate are emitted. It compares each element to the last emitted one, using the predicate to decide
* whether to emit the current element. If the predicate returns `true` for both the last emitted element and the
* current element, the current element is filtered out. Otherwise, the element is emitted.
*
* This function is particularly useful when you need to suppress consecutive duplicates according to a custom
* condition, rather than simply checking for equality.
*
* @param predicate A suspending function that takes an element of type `T` and returns a `Boolean`. The predicate is
* used to determine whether two consecutive elements should be considered duplicates.
* @return A flow that emits only the distinct elements as defined by the predicate.
*/
fun Flow.selectivelyDistinct(predicate: suspend (T) -> Boolean): Flow {
return flow {
var lastEmission: T? = null
collect { value ->
if (lastEmission != null && predicate(lastEmission!!)) {
if (!predicate(value)) {
emit(value)
}
} else {
emit(value)
}
lastEmission = value
}
}
}
/** This simply creates a [channelFlow] and applies the [conflate] operator to the [channelFlow] automatically. */
@OptIn(ExperimentalTypeInference::class)
fun conflatingChannelFlow(@BuilderInference block: suspend ProducerScope.() -> Unit): Flow =
channelFlow(block).conflate()
© 2015 - 2025 Weber Informatics LLC | Privacy Policy