RxSwift: Operators (1) - Filtering Operators

Seoyoung Lee·2023년 11월 5일
0

RxSwift

목록 보기
4/5
post-thumbnail

Operator는 Observable에서 받은 이벤트들을 변환하고 처리할 수 있도록 해준다.

Ignoring Operator

1, 2, 3이라는 세 가지 값을 가지고 있는 시퀀스가 있다고 해보자. ignoreElements() 라는 ignoring operator를 사용하면 시퀀스의 모든 원소들을 무시한다. 그런데 이때도 completed 이벤트는 발생하게 된다.

let strikes = PublishSubject<String>()

let disposeBag = DisposeBag()

strikes
    .ignoreElements()
    .subscribe { _ in
        print("[Subscription is called]")
    }.disposed(by: disposeBag)

strikes.onNext("A")
strikes.onNext("B")
strikes.onNext("C")

위 코드를 실행해보면 아무 것도 출력되지 않는다. ignoreElements() 라는 operator를 실행했기 때문!

이 subscription은 onCompleted 라는 completed 이벤트가 발생했을 때만 호출된다.

strikes.onCompleted()

위 코드를 추가해주면 [Subscription is called] 라는 문구가 잘 출력된다.

Ignoring Operator는 실제 값은 상관없고 observation이 완료되었는지만 구독받고 싶을 때 사용하면 좋다.

elementAt()

어떤 시퀀스가 있을 때 elementAt() 메소드를 사용하면 인자로 전달된 인덱스에 있는 값을 얻을 수 있다.

let strikes = PublishSubject<String>()
let disposeBag = DisposeBag()

strikes.element(at: 2)
    .subscribe(onNext: { _ in
        print("You are out!")
    }).disposed(by: disposeBag)

strikes.onNext("X")
strikes.onNext("X")
strikes.onNext("X") // You are out!

strikes 에서 elementAt() 메소드를 호출하고 구독했다. 이후 세 번째 값이 방출되었을 때 이벤트가 실행이 된다. 두 번째 값까지만 방출하면 이벤트는 실행되지 않는다.

Filter Operator

조건에 맞는 값만 방출하는 operator이다.

let strikes = PublishSubject<String>()
let disposeBag = DisposeBag()

Observable.of(1, 2, 3, 4, 5, 6, 7)
    .filter { $0 % 2 == 0 }
    .subscribe(onNext: {
        print($0)
    }).disposed(by: disposeBag)

// 출력 결과
// 2
// 4
// 6

위 Observable에서 filter() 메소드를 호출하여 짝수 값이 방출될 때만 이벤트가 호출되는 것을 볼 수 있다.

Skip Operator

Skip

파라미터로 받은 숫자만큼 방출된 항목들을 건너뛰는 operator이다.

let strikes = PublishSubject<String>()
let disposeBag = DisposeBag()

Observable.of("A", "B", "C", "D", "E", "F")
    .skip(3)
    .subscribe(onNext: {
        print($0)
    }).disposed(by: disposeBag)

// 실행 결과
// D
// E
// F

SkipWhile

조건식을 만족할 때까지 계속 건너뛴다. 한 번 조건식이 false 가 되면 이후 다른 값들은 모두 시퀀스의 항목에 포함된다.

let strikes = PublishSubject<String>()
let disposeBag = DisposeBag()

Observable.of(2, 2, 3, 4, 4)
    .skip(while: { $0 % 2 == 0 })
    .subscribe(onNext: {
        print($0)
    }).disposed(by: disposeBag)

/* 실행 결과:
3
4
4
*/

SkipUntil

트리거 역할을 하는 Operator가 이벤트를 방출하기 전까지 항목을 건너뛴다.

다른 observable을 기반으로 하기 때문에 동적으로 요소들을 필터링 할 수 있다는 장점이 있다!

let strikes = PublishSubject<String>()
let disposeBag = DisposeBag()

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("X")

subject.onNext("C")

/* 실행 결과
C
*/

trigger 가 항목을 방출한 후에야 subject 의 C라는 항목이 방출된 것을 볼 수 있다.

Taking Operator

Skip Operator와 유사하지만 정반대로 동작하는 operator이다.

Take

처음부터 n개의 항목들만 방출한다.

let strikes = PublishSubject<String>()
let disposeBag = DisposeBag()

Observable.of(1, 2, 3, 4, 5, 6)
    .take(3)
    .subscribe(onNext: {
        print($0)
    }).disposed(by: disposeBag)

/* 실행 결과:
1
2
3
*/

TakeWhile

조건식을 만족하는 동안 항목들을 방출한다. 조건식이 false 가 되면 더 이상 방출을 하지 않는다.

let strikes = PublishSubject<String>()
let disposeBag = DisposeBag()

Observable.of(2, 4, 6, 7, 8, 10)
    .take(while: {
        $0 % 2 == 0
    }).subscribe(onNext: {
        print($0)
    }).disposed(by: disposeBag)

/* 실행 결과:
2
4
6
*/

TakeUntil

트리거 역할을 하는 observable이 항목을 방출하거나 종료되기 전까지 항목들을 방출한다.

let strikes = PublishSubject<String>()
let disposeBag = DisposeBag()

let subject = PublishSubject<String>()
let trigger = PublishSubject<String>()

subject.take(until: trigger)
    .subscribe(onNext: {
        print($0)
    }).disposed(by: disposeBag)

subject.onNext("1")
subject.onNext("2")

trigger.onNext("X")

subject.onNext("3")

/* 실행 결과:
1
2
*/

trigger 가 X라는 항목을 방출하기 전까지만 subject 의 항목이 출력되는 것을 볼 수 있다.

profile
나의 내일은 파래 🐳

0개의 댓글