티스토리 뷰
Map vs FlatMap
1) Map get value from stream and return another value of whatever type, result is Observable<whatever type>.
2) FlatMap get value from stream and return an Observable of whatever type.
Map
map은 이벤트를 바꾼다. E Type이벤트를 R Type이벤트로 바꾼다
public func map<R>(_ transform: @escaping (Self.E) throws -> R) -> RxSwift.Observable<R>
FlatMap
flatMap은 이벤트를 다른 observable로 바꾼다
public func flatMap<O: ObservableConvertibleType>(_ selector: @escaping (E) throws -> O)
-> Observable<O.E>
map은 클로저에 연산 값을, flatMap은 Observable을 리턴시켜줘야한다
예를 들어 Observable<Int> 타입인 numberObservable이 있는데,
number값을 String으로 변환한 Observable<String>을 얻고 싶다면 map과 flatMap은 클로저 리턴 값을 다르게 구성해줘야한다
let numberObservable = Observable<Int>.just(10)
let observableAfterMap = numberObservable.map { String($0) }
let observableAfterFlatMap = numberObservable.flatMap { Observable<String>.just(String($0)) }
하지만 보통 다음과 같은 상황에서 flatMap을 쓰지 않는다
observable로 부터 emit되는 item을 다른 타입으로 바꾸고 싶을때 (observable이 아니라) map이 사용된다
In general, When you have an item emitted from observable and you want to transform them into other type but not an observable then map is preferred.
Map 자주 쓰이는 예제
1)
Float타입의 이벤트를 String타입의 이벤트로 바꿔줄 때 쓰이는 map
map연산을 하면, Observable<Float>에서 Observable<String>으로 바뀐다
slider.rx.value.asObservable()
.map { String($0) }
.bind(to: label.rx.text)
.disposed(by: disposeBag)
2)
textField가 키보드에서 Return을 누르고 들어갈때 그 textField의 값을 가져오는 경우
map연산으로 Observable<()>에서 Observable<String?>으로 바꿔준다
cityNameTextField.rx.controlEvent(.editingDidEndOnExit)
.asObservable()
.map {
return self.cityNameTextField.text
}.subscribe(onNext: { city in
print(city)
}).disposed(by: disposeBag)
3)
서버 응답으로 받은 데이터를 PersonModel로 디코드해준 결과인 Observable<PersonModel>
이 모델에 있는 age값을 label에 뿌려주고 싶은 경우
Observable<PersonModel>.map { "\($0.age)" }
.bind(to: ageLabel.rx.text)
.disposed(by: disposeBag)
FlatMap 자주 쓰이는 예제
buttonTapObservable을 API Call 한 결과인 answers를 가지고 있는 Observable<[String]>으로 바꿔줄 때 쓰이는 flatMap
let answers = Variable<[String]>.init([])
button.rx.tap.asObservable().flatMap { _ -> Observable<[String]> in
return fetchAllAnswers()
}.subscribe(onNext: { newAnswers in
answers.value = newAnswers
}).disposed(by: disposeBag)
func fetchAllAnswers() -> Observable<[String]> {
let api = Observable<[String]>.create { observer in
let answers = API.allAnswers()
observer.onNext(answers)
observer.onCompleted()
return Disposables.create()
}
return api
}
(참고: https://stackoverflow.com/questions/36838248/rxswift-how-to-recall-an-api)
Map과 FlatMap 같이 쓰이는 예제
let url = URL(string: ....)
Observable.just(url)
.flatMap { url -> Observable<Data> in
let request = URLRequest(url: url)
return URLSession.shared.rx.data(request: request)
}.map { data -> [SomeModel]? in
return try? JSONDecoder().decode(SomeModelList.self, from: data).models
}.subscribe(onNext: { [weak self] models in
if let models = models {
self?.models = models
DispatchQueue.main.async {
self?.tableView.reloadData()
}
}
}).disposed(by: disposeBag)
'🍏 > RxSwift' 카테고리의 다른 글
[RxSwift-Operator] reduce와 scan (0) | 2019.04.29 |
---|---|
[RxSwift-Operator] Of와 From (0) | 2019.04.22 |
[RxSwift-Operator] FlatMap과 FlatMapLatest (0) | 2019.04.22 |
[RxSwift] Publish/Behavior/Replay/Async Subject 비교 (1) | 2019.04.04 |
[RxSwift] Subject / Relay / Driver / Variable (2) | 2019.04.04 |
- Total
- Today
- Yesterday
- SerializerMethodField
- Django FCM
- flutter deep link
- 플러터 얼럿
- 장고 Custom Management Command
- METAL
- ribs
- Django Heroku Scheduler
- Watch App for iOS App vs Watch App
- Flutter Spacer
- PencilKit
- flutter dynamic link
- Flutter Text Gradient
- flutter 앱 출시
- 장고 URL querystring
- ipad multitasking
- 플러터 싱글톤
- Python Type Hint
- Flutter Clipboard
- Flutter getter setter
- 구글 Geocoding API
- cocoapod
- flutter build mode
- drf custom error
- Sketch 누끼
- DRF APIException
- github actions
- Dart Factory
- Flutter 로딩
- Django Firebase Cloud Messaging
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |