Skip to content

Instantly share code, notes, and snippets.

@Coronel-B
Created July 9, 2021 22:36
Show Gist options
  • Save Coronel-B/910a564a07156d0f1e7f488bcf1bbc31 to your computer and use it in GitHub Desktop.
Save Coronel-B/910a564a07156d0f1e7f488bcf1bbc31 to your computer and use it in GitHub Desktop.
Combine multiples state flows
/**
* ## Returns a [StateFlow<T>] as a _hot_ whose values are generated with [transform] function by combining
* the most recently emitted values by each state flow.
*
* ### Sample:
*
* ```
* data class A(val a: String)
* data class B(val b: Int)
*
* private val test1 = MutableStateFlow(A("a"))
* private val test2 = MutableStateFlow(B(2))
* @Suppress("CHANGING_ARGUMENTS_EXECUTION_ORDER_FOR_NAMED_VARARGS")
* private val _isValidForm = combineStateFlow(
* flows = arrayOf(test1, test2),
* scope = viewModelScope
* ) { combinedFlows: Array<Any> ->
* combinedFlows.map {
* val doSomething = when (it) {
* is A -> true
* is B -> false
* else -> false
* }
* }
* }
*
* ```
*
* **Sources:**
* - Combine two state flows: https://stackoverflow.com/a/65444578/5279996
* - Vararg: https://stackoverflow.com/a/65520425/5279996
*/
@Suppress("CHANGING_ARGUMENTS_EXECUTION_ORDER_FOR_NAMED_VARARGS")
inline fun <reified T, R> combineStateFlow(
vararg flows: StateFlow<T>,
scope: CoroutineScope = GlobalScope,
sharingStarted: SharingStarted = SharingStarted.Eagerly,
crossinline transform: (Array<T>) -> R
): StateFlow<R> = combine(flows = flows) {
transform.invoke(it)
}.stateIn(
scope = scope,
started = sharingStarted,
initialValue = transform.invoke(flows.map {
it.value
}.toTypedArray())
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment