Search code examples
iostuplescombinepublisher

How to FlatMap a Publisher of two Tuples into a Publisher with one Tuple


I have the following code

 private var codeState : AnyPublisher<((Bool,Bool,Bool,Bool),(Bool,Bool)), Never> {
    let publ1 =  Publishers.CombineLatest4(firstCodeAnyPublisher,secondCodeAnyPublisher,thirdCodeAnyPublisher,fourthCodeAnyPublisher)
    let pub2 = Publishers.CombineLatest(fifthCodeAnyPublisher, sixthCodeAnyPublisher)
    return publ1.combineLatest(pub2)
        .eraseToAnyPublisher()
}

This operation produces any publisher with two boolean tuple How can I convert them to a publisher with one tuple the following

AnyPublisher<(Bool,Bool,Bool,Bool,Bool,Bool), Never>

Solution

  • I feel compelled to say that publishing a tuple of two unnamed Bools or four unnamed Bools or six unnamed Bools is probably a bad idea. You should at least label the values, and probably you should create structs instead of using tuples.

    That said, you can apply the map operator to merge the tuples:

    private var codeState : AnyPublisher<(Bool,Bool,Bool,Bool,Bool,Bool), Never> {
        let publ1 =  Publishers.CombineLatest4(firstCodeAnyPublisher,secondCodeAnyPublisher,thirdCodeAnyPublisher,fourthCodeAnyPublisher)
        let pub2 = Publishers.CombineLatest(fifthCodeAnyPublisher, sixthCodeAnyPublisher)
        return publ1.combineLatest(pub2)
            .map { ($0.0, $0.1, $0.2, $0.3, $1.0, $1.1) }
            .eraseToAnyPublisher()
    }
    

    In fact, combineLatest has an overload that takes the transform function as an extra argument and applies map for you, so can also write it this way:

    private var codeState : AnyPublisher<(Bool,Bool,Bool,Bool,Bool,Bool), Never> {
        let publ1 =  Publishers.CombineLatest4(firstCodeAnyPublisher,secondCodeAnyPublisher,thirdCodeAnyPublisher,fourthCodeAnyPublisher)
        let pub2 = Publishers.CombineLatest(fifthCodeAnyPublisher, sixthCodeAnyPublisher)
        return publ1.combineLatest(pub2) {
            ($0.0, $0.1, $0.2, $0.3, $1.0, $1.1)
        }
        .eraseToAnyPublisher()
    }
    

    You should use whichever version you find easier to understand. Neither one is more efficient than the other.