Description
Use case
I'm working on an Android app, specifically on a screen for composing a new post for social media. We're using Jetpack Compose, following the NowInAndroid example. This means we have a bunch of private states and the final UI state is the combination of those, like:
private val config: StateFlow<Config> = getConfigUseCase()
private val text: StateFlow<String> = MutableStateFlow("")
private val scheduledDate: StateFlow<Long?> = MutableStateFlow(null)
...
val state = combine(
config,
text,
scheduledDate,
...,
::toUiState
)
The screen is fairly complex, there are a lot of local states and we hit the limit of the method
combine(
flow: Flow<T1>,
flow2: Flow<T2>,
flow3: Flow<T3>,
flow4: Flow<T4>,
flow5: Flow<T5>,
transform: suspend (T1, T2, T3, T4, T5) -> R
): Flow<R>
that accepts at most 5 elements. We used the provided method
combine(vararg flows: Flow<T>, crossinline transform: suspend (Array<T>) -> R): Flow<R>
but we didn't like manual casting wherever we used it, so we ended up creating methods combine(...)
Eventually we ended up writing methods that support up to 10 elements like this:
fun <T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, R> combine(
flow: Flow<T1>,
flow2: Flow<T2>,
flow3: Flow<T3>,
flow4: Flow<T4>,
flow5: Flow<T5>,
flow6: Flow<T6>,
flow7: Flow<T7>,
flow8: Flow<T8>,
flow9: Flow<T9>,
flow10: Flow<T10>,
crossinline transform: suspend (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10) -> R,
): Flow<R> = kotlinx.coroutines.flow.combine(flow, flow2, flow3, flow4, flow5, flow6, flow7, flow8, flow9, flow10) { args: Array<*> ->
@Suppress("UNCHECKED_CAST")
transform(
args[0] as T1,
args[1] as T2,
args[2] as T3,
args[3] as T4,
args[4] as T5,
args[5] as T6,
args[6] as T7,
args[7] as T8,
args[8] as T9,
args[9] as T10,
)
}
Now the question arose if these should be present in the Coroutines code itself, specifically in the flow.operators.Zip?
If you'd be interested in this, I can add combine
methods for 6, 7, 8, 9 and 10 elements. Let me know.