[RxSwift] Zip

2020-01-14

역할

두 개 이상의 Observable에서 방출된 순서가 같은 아이템을 묶어서 하나의 아이템으로 방출합니다.

zip

예제

[코드]

let disposeBag = DisposeBag()
    
let numSubject = PublishSubject<Int>()
let charSubject = PublishSubject<String>()
    
let zippedObservable = Observable.zip(numSubject, charSubject)
    
zippedObservable
    .subscribe(onNext: { print($0) })
    .disposed(by: disposeBag)
    
numSubject.onNext(1)
charSubject.onNext("A")
numSubject.onNext(2)
charSubject.onNext("B")
charSubject.onNext("C")
charSubject.onNext("D")
numSubject.onNext(3)
numSubject.onNext(4)
numSubject.onNext(5)

[실행 결과]

(1, "A")
(2, "B")
(3, "C")
(4, "D")

numSubject의 아이템 5에 대해서는 charSubject에서 같은 순서에 방출된 아이템이 없으므로 zip 결과로 아무런 아이템도 방출되지 않습니다.

활용

같은 순서쌍으로 처리해야하는 작업에 사용하면 편리 합니다.

예를들면, UITableView에서 선택한 Cell의 indexPath와 그 indexPath에 해당하는 model을 보장하는 처리를 하고 싶을때 zip을 사용할 수 있습니다.

첫번째 Observable: UITableView에서 선택된 아이템의 indexPath

두번째 Observable: UITableView에서 선택된 아이템의 model

[코드]

Observable.zip(tableView.rx.itemSelected, tableView.rx.modelSelected(ServiceType.self))
.subscribe(onNext: { [weak self] (indexPath, serviceType) in
    self?.tableView.deselectRow(at: indexPath, animated: false)
    self?.selectedServiceType.accept(serviceType)
})
.disposed(by: disposeBag)

indexPath을 이용해 선택된 Cell을 deselect하고, model은 선택된 Cell의 모델을 관리하기 위해 사용합니다.

[참 고]