Skip to content

Adding combine(...) methods to combine 6-10 flows #3598

Open
@koncinar

Description

@koncinar

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.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions