Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

RxSwift map and flatMap difference

Tags:

swift

rx-swift

I can't understand the difference between map and flatMap In RxSwift. In the RxSwift playground examples and the books, flatMap is used as converting Observables which has inner Observable property.

However I see flatMap being used directly on Observable of basic types. For example for below code, both of them produces the same output. Can someone help me to understand the difference between map and flatMap

struct Student {
    let score:Int
}

let ryan = Student(score:80)
let student = PublishSubject<Student>()

let deneme = student.map({ val in
    return Student(score: val.score+10)
})
deneme.subscribe(onNext: {
    print("StudentMAP: \($0.score)")
})

let deneme2 = student.flatMap({ val -> Observable<Student> in
    return Observable.of(Student(score: val.score + 10))
})

deneme2.subscribe(onNext: {
    print("StudentFlatMAP: \($0.score)")
})

 student.onNext(ryan)
like image 943
Meanteacher Avatar asked Apr 03 '18 10:04

Meanteacher


1 Answers

map get value from stream and return another value of whatever type, result is Observable< whatever type >.

flatMap get value from stream and return an Observable of whatever type.

This means you can use flatMap when:

  • you already have a function declared which returns Observable< ? >, so you may want to use it in flatMap

    func foo(_ number: Int) -> Observable<String> {
        return Observable.just(String(number))
    }
    
    Observable.just(1)
        .flatMap { (number) -> Observable<String> in
            return foo(number)
    }
    
  • you need that returned value push more than one value in the stream

    func updates() -> Observable<String> {
        // Something that generates updates
    }
    
    func shouldListenToUpdated() -> Observable<Bool> {
        return Observable.just(true)
    }
    
    shouldListenToUpdated()
        .flatMap { (listenToUpdated) -> Observable<String> in
            return listenToUpdated ? updates() : Observable.empty()
    }
    

While map will just transform next value in the stream.

Hope this clarifies things a bit.

like image 66
Evghenii Nicolaev Avatar answered Nov 04 '22 14:11

Evghenii Nicolaev