RxSwift

Operator

motosw3600 2022. 2. 9. 16:50

Operator

  • Operator를 통해 발행된 이벤트들을 조건을 걸어 원하는 이벤트로 전달 가능
  • Swift Collection의 filter와 비슷한 개념 

Ignoring Operator

Filter

  • Bool을 리턴하는 클로저를 받아 Observable Event확인
  • 클로저안 조건을 만족하는 이벤트만 방출

let disposeBag = DisposeBag()

Observable.of(1, 2, 3)
    .filter { $0 < 3 }
    .subscribe(onNext: {
        print($0)
    })
    .disposed(by: disposeBag)

// 1
// 2

ignoreElements

  • .next 이벤트를 무시
  • 종료 이벤트는 전달(.error, .complete)
  • 시퀀스의 종료 시점만 확인 가능

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

subject
    .ignoreElements()
    .subscribe { event in
        print("Completed!!")
    }
    .disposed(by: disposeBag)

subject.onNext("1")
subject.onNext("2")
subject.onNext("3")
subject.onCompleted()
// Completed!!

Element At

  • Obeservable에서 발행된 이벤트중 n번째 이벤트만 받고 싶을 경우

let disposeBag = DisposeBag()
Observable<Int>.of(1, 2, 3)
    .element(at: 1)
    .subscribe(onNext: {
        print($0)
    })
    .disposed(by: disposeBag)
    
// 2

 


Skipping Operator

skip

  • 특정 개수만큼 이벤트를 skip

let disposeBag = DisposeBag()
Observable.of(1, 2, 3)
    .skip(2)
    .subscribe(onNext: {
        print($0)
    })
    .disposed(by: disposeBag)
 
// 3

skip(while:)

  • 조건에 만족하는 경우만 계속 skip
  • 일회성으로 한번조건을 만족하면 skip종료

let disposeBag = DisposeBag()
Observable.of(1, 2, 3, 4)
    .skip(while: { $0 % 2 == 1 })
    .subscribe(onNext: {
        print($0)
    })
    .disposed(by: disposeBag)
    
// 2
// 3 (skipWhile은 일회성)
// 4

 

skip(until:)

  • 별개의 subject를 두고, 이 이벤트가 발생하기 전까지 event들을 skip
  • Dynamic하게 Sequence 제어 가능

let disposebag = DisposeBag()

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

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

subject.onNext("1") // skip

trigger.onNext("trigger") // trigger

subject.onNext("2") // 2
subject.onNext("3") // 3

 


Taking Operator

take

  • skip의 반대 개념
  • 처음 발생한 이벤트부터 n개까지의 이벤트만 수신

let disposeBag = DisposeBag()

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

take(while:)

  • 클로저안의 조건을 만족할 때 까지 이벤트 수신, skipWhile과 비슷
  • 조건을 만족 못한경우 그 후의 이벤트까지 다 무시

let disposeBag = DisposeBag()

Observable.of(1, 2, 3)
    .take(while: { $0 < 3 })
    .subscribe(onNext: {
        print($0)
    })
    .disposed(by: disposeBag)
    
// 1
// 2

take(until:)

  • trigger하는 Sequence까지의 이벤트 수신, 이후의 이벤트는 무시

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") // 1
trigger.onNext("trigger") // trigger

subject.onNext("2") // 이후 발행된 이벤트 무시
subject.onNext("3") // 이후 발행된 이벤트 무시

 


DisTinct Opertators

distinctUntilChanged

  • 바로 전에 발생한 동일한 이벤트에 대한 중복값 방지
  • Equatable을 통해 값비교, 클로저로 비교 조건 설정 가능

let disposeBag = DisposeBag()

Observable.of(1, 1, 2, 2, 1)
    .distinctUntilChanged()
    .subscribe(onNext: {
        print($0)
    })
    .disposed(by: disposeBag)
    
// 1
// 2
// 1

 

클로저를 사용한 disticntUntilChanged

let disposeBag = DisposeBag()

let formatter = NumberFormatter()
formatter.numberStyle = .spellOut

Observable<NSNumber>.of(10, 110, 20, 200, 210, 310)
    .distinctUntilChanged { a, b in
        guard let aWords = formatter.string(from: a)?.components(separatedBy: " "),
                let bWords = formatter.string(from: b)?.components(separatedBy: " ") else { return false }
        
        var containsMatch = false
        
        for aWord in aWords {
            if bWords.contains(aWord) {
                containsMatch = true
                break
            }
        }
        
        return containsMatch
    }
    .subscribe(onNext: {
        print($0)
    })
    .disposed(by: disposeBag)
    }
    
// 10 (ten, one hundred ten)
// 20 (two hundred, two hundred ten)
// 200 (two hundred, three hundred ten)


참고 : raywenderlich RxSwift Programming with Swift

'RxSwift' 카테고리의 다른 글

RxFlow  (0) 2022.03.30
RxViewController  (0) 2022.03.03
Subject  (0) 2022.02.08
Observable  (0) 2022.02.07
RxSwift란?  (0) 2022.02.07