CombineExt icon indicating copy to clipboard operation
CombineExt copied to clipboard

Add flatMapFirst

Open mesheilah opened this issue 5 years ago • 5 comments
trafficstars

While there's no switchToFirst operator in Combine, I find it very challenging to implement flatMapFirst like operator from scratch, I'd suggest to start building this operator which's really useful for many use cases

mesheilah avatar Aug 12 '20 11:08 mesheilah

It's a great idea but would require and implementor with motivation that needs it. I don't have a use case for it so clearing my time to write it would be a bit tricky...

freak4pc avatar Nov 21 '20 09:11 freak4pc

What about this?

public extension Publisher {
    func flatMapFirst<P: Publisher>(
        _ transform: @escaping (Output) -> P
    ) -> Publishers.FlatMap<Publishers.HandleEvents<P>, Publishers.Filter<Self>>
    where Self.Failure == P.Failure {
        var isRunning = false
        let lock = NSRecursiveLock()

        func set(isRunning newValue: Bool) {
            defer { lock.unlock() }
            lock.lock()

            isRunning = newValue
        }

        return self
            .filter { _ in !isRunning }
            .flatMap { output in
                transform(output)
                    .handleEvents(
                        receiveSubscription: { _ in
                            set(isRunning: true)
                        },
                        receiveCompletion: { _ in
                            set(isRunning: false)
                        },
                        receiveCancel: {
                            set(isRunning: false)
                        }
                    )
            }
    }
}

troupmar avatar Aug 20 '21 09:08 troupmar

@troupmar Care to add that as a pull request? I use flatMapFirst a lot in my RxSwift code so I would need this to switch to Combine. It would be nice to have everything I need in one library.

danielt1263 avatar Nov 06 '21 13:11 danielt1263

@danielt1263 Hi there, I will try to make a pull request but at this time I am very busy. The pull request will require some additional tests. At this point it would be useful if somebody could overview the implementation, at least to know if it seems to be correct. Then if I happen to have some time, I will be happy to complete it and prepare a pull request.

troupmar avatar Feb 24 '22 19:02 troupmar

Here it is: https://github.com/CombineCommunity/CombineExt/pull/119

troupmar avatar Mar 22 '22 14:03 troupmar