[Swift] RxSwift - Filtering Operators(2)

호랭이·2022년 5월 16일
0

🍎 RxSwift

목록 보기
4/6

👈 이전 글
RxSwift-Filtering-Operators(1)

Filtering Orerators(1)

.next 이벤트를 통해 받아오는 값을 선택적으로 취할 수 있다.

목차

  • Taking operators
    - .take
    - .takeWhile
    - .enumerated
  • Distinct operators
    - .distinctUntilChanged
    - .distinctUntilChanged(_:)

Taking operators

  • Takingskip과 반대 개념이다.
  • 특정 요소를 취하고 싶을 때 사용하는 연산자

.take

  • take(2)를 통해서 처음 2개의 값을 취함

.takeWhile

  • skipWhile과 비슷하게, 조건문에 대해 true일 경우 값을 방출하다가 false를 만나면 종료된다.

.enumerated

  • Swift의 enumertated 메소드와 비슷하게, Observable이 가진 각 요소의 index와 값을 갖는 튜플을 생성한다.
 example(of: "takeWhile") {
     let disposeBag = DisposeBag()
     
     // 1
     Observable.of(2,2,4,4,6,6)
         // 2
         .enumerated()
         // 3
         .takeWhile({ index, value in
             value % 2 == 0 && index < 3
         })
         // 4
         .map { $0.element }
         // 5
         .subscribe(onNext: {
             print($0)
         })
         .disposed(by: disposeBag)
 }
  1. Observable 생성
  2. .enumerated를 이용하여 index와 값을 갖는 튜플 생성
  3. index가 3미만이고 값이 짝수인 경우 요소를 방출하다가, 조건문에 대하여 false인 요소를 만나면 종료
  4. .map을 통해 방출된 튜플의 값만 추출
  5. 값 출력

.takeUntil

  • skipUntil과 비슷하게, trigger가 되는 Observable이 구독되기 전까지의 이벤트 값만 받는다.
 example(of: "takeUntil") {
     let disposeBag = DisposeBag()
     
     // 1
     let subject = PublishSubject<String>()
     let trigger = PublishSubject<String>()
     
     // 2
     subject
         .takeUntil(trigger)
         .subscribe(onNext: {
             print($0)
         })
         .disposed(by: disposeBag)
     
     // 3
     subject.onNext("1")
     subject.onNext("2")
     
     // 4
     trigger.onNext("X")
     
     // 5
     subject.onNext("3")
 }
  1. subjecttrigger라는 PublishSubject<String> 생성
  2. .takeUntil을 통해 trigger 연결 및 subscribe
  3. subject에 이벤트 추가
  4. trigger에 이벤트 추가. 여기서 subject가 값을 취하는 것을 멈춘다.
  5. 4번에서 trigger를 통해 subject에 이벤트값을 받는 것을 멈추었기 때문에 이벤트가 출력되지 않는다.

Distinct operators

  • 중복해서 이어지는 값을 막아준다.

distinctUntilChanged

  • 연속되서 중복된 2는 최초의 값만 방출된다.
  • 1은 중복되었지만 연속되지 않았기 때문에 그대로 방출된다.

distinctUntilChanged(_:)

  • distinctUntilChanged은 기본적으로 구현된 로직에 따라 중복과 연속을 확인하는데, 이 메소드는 로직을 커스텀 할 수 있다.
 example(of: "distinctUntilChanged(_:)") {
     let disposeBag = DisposeBag()
     
     // 1
     let formatter = NumberFormatter()
     formatter.numberStyle = .spellOut
     
     // 2
     Observable<NSNumber>.of(10, 110, 20, 200, 210, 310)
         // 3
         .distinctUntilChanged({ a, b in
             //4
             guard let aWords = formatter.string(from: a)?.components(separatedBy: " "),
                 let bWords = formatter.string(from: b)?.components(separatedBy: " ") else {return false}
             
             var containsMatch = false
             
             // 5
             for aWord in aWords {
                 for bWord in bWords {
                     if aWord == bWord {
                         containsMatch = true
                         break
                     }
                 }
             }
             
             return containsMatch
         })
         // 6
         .subscribe(onNext: {
             print($0)
         })
         .disposed(by: disposeBag)
 }
  1. 번호를 배출해내는 NumberFormatter() 생성
  2. NSNumbers Observable 생성
  3. 각각의 seuquence 쌍을 받는 클로저 distinctUntilChanged(_:) 생성
  4. 값의 구성요소를 바인딩하고 실패 시 false 반환
  5. 튜플 값의 단어들을 반복하고 검사 결과를 반환하여 동일한 단어를 포함하는지 확인
  6. 구독과 출력
profile
삐약

0개의 댓글