일부 RxSwift의 Filtering 연산자에 대한 정리 🚌 🚌 🚌
연산자 목차
- ignoreElement
- element(at:)
- filter
- skip / skip while / skip until
- take / take while / take until
- debounce
- distinctUntilChanged
- sample
ignoreElements
element를 전부 무시하는 연산자입니다.
방출되는 element는 모두 무시하고 마지막 complete되는 시점만 알고 싶을 때 사용합니다.
let disposeBag = DisposeBag()
let subject = PublishSubject<String>()
subject
.ignoreElements()
.subscribe { _ in
print("End")
}.disposed(by: disposeBag)
subject.onNext("A")
subject.onNext("B")
subject.onNext("C")
subject.onCompleted()
출력
// End
위 출력은 dispose될 때 출력되는 것으로 아래와 같이 사용할 수도 있습니다.
subject
.ignoreElements()
.subscribe(onDisposed: {
print("End")
}).disposed(by: disposeBag)
element(at:)
해당 index일 경우 방출하는 연산자입니다. element(at: 2) 라면 index가 2일 때 방출됩니다.
subject
.element(at: 2)
.subscribe(onNext: { _ in
print("Hello")
}).disposed(by: disposeBag)
subject.onNext("A") // 출력 X
subject.onNext("B") // 출력 X
subject.onNext("C") // Hello
subject.onNext("D") // 출력 X
출력
// Hello
한번만! 출력됩니다.
filter
지정 조건으로 필터링해주는 연산자입니다. 기존 swift에 있는 필터링 함수와 같습니다.
아래는 짝수로 필터링해주는 예제입니다.
let disposeBag = DisposeBag()
Observable.of(1,2,3,4,5,6,7,8,9)
.filter { $0 % 2 == 0 }
.subscribe(onNext: {
print($0)
}).disposed(by: disposeBag)
출력
// 2
// 4
// 6
// 8
skip
skip(N)은 N만큼 skip하고 방출하는 연산자입니다.
Observable.of(1,2,3,4,5,6,7,8,9)
.skip(5)
.subscribe(onNext: {
print($0)
}).disposed(by: disposeBag)
출력
// 6
// 7
// 8
// 9
skip while
지정 조건에 해당되면 계속 skip하다가 해당되지 않은 element일 경우 거기서부터 방출하는 연산자입니다. 이후부터 조건에 해당되더라도 skip되지 않고 전부 방출됩니다.
filter 연산자는 조건을 전부 필터링 해주었다면, skip while은 조건이 나온 시점 이후부터는 전부 방출합니다.
Observable.of(2,2,3,4,4,5)
.skip(while: { $0 % 2 == 0})
.subscribe(onNext: {
print($0)
}).disposed(by: disposeBag)
출력
// 3
// 4
// 4
// 5
skip until
마블 다이어그램을 보면 두개의 observable과 결과 observable이 있습니다. 여기서 중간 observable은 trigger 역할을 하여 이 trigger가 방출될 때까지 상단 observable은 skip하다 trigger가 방출되면 그 이후부터 방출하는 연산자입니다.
let subject = PublishSubject<String>()
let trigger = PublishSubject<String>()
subject.skip(until: trigger)
.subscribe(onNext: {
print($0)
}).disposed(by: disposeBag)
subject.onNext("A")
subject.onNext("B")
trigger.onNext("Go")
subject.onNext("C")
출력
// C
take
take(N)은 N만큼 앞에서부터 가져오는(take) 연산자입니다. skip 연산자와 반대입니다.
Observable.of(1,2,3,4,5,6)
.take(3)
.subscribe(onNext: {
print($0)
}).disposed(by: disposeBag)
출력
// 1
// 2
// 3
take while
지정 조건에 해당되면 모두 방출하지만 해당되지 않은 element일 경우 거기서부터 방출하지 않습니다. 이후부터 조건에 해당되더라도 방출되지 않고 전부 skip합니다. skip while 연산자와 반대로 동작합니다.
Observable.of(2,4,6,7,8,10)
.take(while: { $0 % 2 == 0 })
.subscribe(onNext: {
print($0)
}).disposed(by: disposeBag)
출력
// 2
// 4
// 6
take until
skip until과 반대로 동작합니다. 마블 다이어그램을 보시면 trigger Observable이 방출될때까지 방출되다가 그 이후부터는 방출되지 않습니다.
let subject = PublishSubject<String>()
let trigger = PublishSubject<String>()
subject.take(until: trigger)
.subscribe(onNext: {
print($0)
}).disposed(by: disposeBag)
subject.onNext("A")
subject.onNext("B")
trigger.onNext("Stop")
subject.onNext("C")
출력
// A
// B
debounce
지정한 시간만큼 지나지 않으면 방출하지 않는 연산자입니다.
버튼을 연속해서 누르면 안되는 경우, 검색할 때 타자를 칠 때마다 자동완성되어야 하는 경우(매 타자마다 API 통신이 이루어저야 하는 경우)에 쓰이면 유용할 것 같습니다.
throttle 도 함께 익혀두면 좋을 것 같습니다.
debounce와 throttle 동작 차이점을 알려주는 글 👉 https://medium.com/fantageek/throttle-vs-debounce-in-rxswift-86f8b303d5d4
button.rx.tap
.debounce(.seconds(1), scheduler: MainScheduler.asyncInstance)
distinctUntilChanged
이전에 방출한 연산자와 다른 element일 경우 방출하는 연산자입니다.
Observable.of(1,2,2,2,5,2)
.distinctUntilChanged()
.subscribe(onNext: {
print($0)
}).disposed(by: disposeBag)
출력
// 1
// 2
// 5
// 2
Sample
가장 최근에 방출한 item을 trigger가 방출한 시점에 방출합니다.
만약 trigger가 발생했을 때 이전 trigger에서 가장 최근에 방출한 item과 같은 item이라면 방출하지 않습니다. 즉, time도 고려합니다.
마블 다이어그램에서 A,B,D는 trigger Observable이므로 방출되지만 C는 이전에 방출되었던 2와 같은 값을 방출해야하므로 trigger이지만 방출되지 않습니다. (default 값을 지정하여 방출해줄 수 있습니다.)
let subject = PublishSubject<String>()
let trigger = PublishSubject<String>()
subject.sample(trigger, defaultValue: nil)
.subscribe(onNext: {
print($0)
}).disposed(by: disposeBag)
subject.onNext("A")
subject.onNext("B")
trigger.onNext("Go")
subject.onNext("C")
trigger.onNext("Go")
trigger.onNext("Go")
subject.onNext("C")
trigger.onNext("Go")
출력
// B
// C
// C
출처
- https://reactivex.io/documentation/operators.html
- https://www.udemy.com/course/mastering-rxswift-in-ios/learn/lecture/
'iOS > RxSwift' 카테고리의 다른 글
[Operators] Combining (0) | 2022.01.31 |
---|---|
[Operators] Transforming (0) | 2022.01.30 |
[Observables] 개념 (0) | 2021.05.14 |