嗨!今天要講Filtering Observables,它能約束訂閱者收到的元素,感覺就很像是在Swift當中使用filter
一樣,同樣的,Filtering實在太多種類了,這裡就介紹我常用或有趣的。
這個超常用,用法跟Swift的.filter
一樣,給定條件,符合條件的才會發送給訂閱者,這邊我在.filter
前後都加上.debug()
,方便看出前後的不同,各位嘗試的時候可以使用emoji。
Observable.of(1, 2, 3, 4, 5)
.debug("A")
.filter { $0 % 2 == 1 }
.debug("B")
.subscribe()
.disposed(by: disposeBag)
結果如下,從列印的結果就能看到只有基數被發送出來
B -> subscribed
A -> subscribed
A -> Event next(1)
B -> Event next(1)
A -> Event next(2)
A -> Event next(3)
B -> Event next(3)
A -> Event next(4)
A -> Event next(5)
B -> Event next(5)
A -> Event completed
B -> Event completed
B -> isDisposed
A -> isDisposed
實際開發上,可能會遇到這種情境,MyResult類別中有code變數,他代表API回傳結果的各種狀況,我們需要在 code是A跟不是A的時候做不同的事情,也許我們就可以像下面這樣寫,先用.filter
分成不同的condition,再去 transform或combine其他Observable,這部份過幾天就講到了!
let subject = PublishSubject<MyResult>()
let observer = subject.asObserver()
let observable = subject.asObservable()
let conditionA = observable.filter { $0.code == "A" }
let conditionB = observable.filter { $0.code != "A" }
conditionA.map { _ in neededDataA }
conditionB.map { _ in neededDataB }
顧名思義它會略過一些元素,他有幾個很相似的operator,我們下面會放一起講
Observable.of(1, 2, 3, 4, 5)
.skip(2)
.debug("B")
.subscribe()
.disposed(by: disposeBag)
列印結果如下
B -> subscribed
B -> Event next(3)
B -> Event next(4)
B -> Event next(5)
B -> Event completed
B -> isDisposed
定義『略過符合條件的元素,直到遇到不符合條件的元素(即 false),就停止略過』
Observable.of(1, 3, 5, 6, 7)
.skipWhile { $0 % 2 == 1 }
.debug("B")
.subscribe()
.disposed(by: disposeBag)
結果如下
B -> subscribed
B -> Event next(6)
B -> Event next(7)
B -> Event completed
B -> isDisposed
定義『略過元素,直到另一個Observable發送元素,就停止略過』,跟前面兩種相比,前面兩種是靜態的設定過濾條件,skipUntil
則是可以基於另一個Observable 去動態過濾元素。
let subject = PublishSubject<String>()
let trigger = PublishSubject<Void>()
subject
.skipUntil(trigger)
.debug("B")
.subscribe()
.disposed(by: disposeBag)
subject.onNext("1")
subject.onNext("2")
trigger.onNext(())
subject.onNext("3")
subject.onNext("4")
結果會是這樣
B -> subscribed
B -> Event next(3)
B -> Event next(4)
說實在,我比較常用的只有skip
,在某些情況下可能需要略過第一個元素,可以寫成.skip(1)
,但operator 就是多學一個,之後說不定就有機會用到了!
take
跟skip
就是相反的存在,前者是取的n個元素,後者是略過n個元素,同樣的,它也有takeWhile
跟takeUntil
。
除此之外,他還有一個takeLast
,只取最後n個元素,下面就直接展示takeLast
的範例程式,有興趣的人可以自己嘗試看看其他的。
Observable.of(1, 2, 3, 4, 5)
.takeLast(2)
.debug("B")
.subscribe()
.disposed(by: disposeBag)
執行結果如下,只取最後 2 個元素
B -> subscribed
B -> Event next(4)
B -> Event next(5)
B -> Event completed
B -> isDisposed
定義『排除重複的元素,直到不是重複時,才會發出』,比如下方範例,當true轉false時才會發送元素
Observable.of(true, true, false, false, true, false)
.distinctUntilChanged()
.debug("B")
.subscribe()
.disposed(by: disposeBag)
執行結果
B -> subscribed
B -> Event next(true)
B -> Event next(false)
B -> Event next(true)
B -> Event next(false)
B -> Event completed
B -> isDisposed
你也可以制定重複的定義,像以下這樣,
Observable.of(1, 7, 3, 5, 9)
.distinctUntilChanged { prev, curr in prev > curr }
.debug("B")
.subscribe()
.disposed(by: disposeBag)
執行結果
B -> subscribed
B -> Event next(1)
B -> Event next(7)
B -> Event next(9)
B -> Event completed
B -> isDisposed
今天講了Filtering,明天會講Transforming,陸續這幾天會把operator大致了解過一遍,掰掰