Chapter 7 challenge

Hello,
I am having hard time understanding the return types of map and flatMap.

While working on challenge from chapter 7 I have solved it in a different way than it is solved in the final project file. I have noticed something strange about the return types.

Shouldn’t both flatMap and map return the same type - Observable sequence instead of UInt value?

input.asObservable()
    .flatMap{
        convert($0) == nil ? Observable.empty() : Observable.just(convert($0)!)
    }
    .skipWhile{$0 == 0}
    .take(10)
    .toArray()
    .map(format)
    .subscribe(onNext: {
        print(dial($0))
    })
    .addDisposableTo(disposeBag)

Thanks in advance if anyone who understands this can find a time and explain it to me :slight_smile:

Thank you for the heads up and pointing this one out - much appreciated! @scotteg Can you please take care of this one when you actually get a chance after all? Thanks! :]

Hi @arminas_r, I used to get confused with map and flatMap. It took me some time and practice to straighten up, let me put my 2 cents here.

map transforms elements of an observable sequence. In your case, input.asObservable() is an observable sequence of type Observable<String>, its String type elements are then transformed to elements of type Observable<UInt>, so type Observable<Observable<UInt>> is what you eventually get from map. As a result, the elements you are working on with .skipWhile are of type Observable<UInt>, as the compiler shows to you.

flatMap on the other hand, applies transform → flatten sequence to each of the elements of an observable sequence. In this case, flatMap transforms an element of type String to an observable sequence of type Observable<UInt>, it then flattens down this transformed observable sequence to use only its elements (type UInt) to put on to the final observable sequence which - as a result - is of type Observable<UInt>. So you have UInt with the following .skipWhile.

Hi @arminas_r,

Yes, flatMap and map both return an observable. However, within the skipWhile operator, you are looking at the argument passed to the closure, which is the element itself.

public func skipWhile(_ predicate: @escaping (E) throws -> Bool) -> Observable<E> {
    return SkipWhile(source: asObservable(), predicate: predicate)
}

skipWhile takes a predicate parameter that is a throwing closure, which takes an instance of E (associated type generically representing the element type of the observable) and returns a Bool, and skipWhile returns an observable of the element.

Thank you @zuchie and @scotteg,
The difference between flatMap and map is a bit confusing. However, knowing that map only transforms and flatMap transform → flatten explains why I have a different output from them.
I can understand now why I have UInt with the following .skipWhile after flatMap and Observable after map.

You are welcome, glad to help.

This topic was automatically closed after 166 days. New replies are no longer allowed.