Search code examples
swiftcombine

Chaining array of AnyPublishers


I'm wondering if there is a way to chain array of publishers similar to how we chain publishers with regular flatMap

Let's say I have three publishers: publisher1, publisher2, publisher3 all of them have the same Output, Failure types. For example, each of them is AnyPublisher<String, Never> and emits a single String value. The only role of each publisher is to fetch its own value and emits previous value joined with its own.

I'm looking for same effect as from the following pseudo code:

let pipe = publisher1(value: "")
      .flatMap { publisher2(value: $0) }
      .flatMap { publisher3(value: $0) }

Execution flow:

publisher1 (fetches "A") -> publisher2 (fetches "B") -> publisher3 (fetches "C") -> "ABC"

I would like to reproduce the same flow for the array with unknown count of publishers n ([AnyPublisher<String, Never>])

1 -> 2 -> 3 -> ... -> n

I'll appreciate any tips, thanks! :)


Solution

  • First of all, let's clarify your question. Based on your description of wanting to create a chain of flatMap-ed publishers, what you must have is an array of closures - not publishers - each returning an AnyPublisher<String, Never> publisher given a String parameter.

    let pubs: [(String) -> AnyPublisher<String, Never>] = [
        publisher1, publisher2, publisher3 
    ]
    

    To chain them, you could use a reduce method of the array by starting with a Just publisher to emit the initial parameter:

    let pipe = pubs.reduce(Just("").eraseToAnyPublisher()) { acc, next in
       acc.flatMap { next($0) }.eraseToAnyPublisher()
    }