본문 바로가기

개발/RxSwift

[RxSwift] Filtering Observable

반응형
 

ReactiveX - Operators

Introduction Each language-specific implementation of ReactiveX implements a set of operators. Although there is much overlap between implementations, there are also some operators that are only implemented in certain implementations. Also, each implementa

reactivex.io

 

Filtering Observable

이벤트들이 특정 조건이 맞을 때 발생하도록 이벤트를 필터링 하는 메서드다.

 

Filtering Observable 종류

  • Debounce
  • Distinct
  • ElementAt
  • Filter
  • First
  • IgnoreElements
  • Sample
  • Skip
  • Take
  • TakeLast

 


 

Debounce

Debounce

항목을 배출한 이후, 특정 시간이 경과하면 다른 항목을 배출하도록 하는 Observable이다.
Observable에서 방출된 항목 중 빠르게 이어지는 항목을 필터링한다.
사용 사례는 스크롤 등 한 번의 인식이 필요하나 여러 동작이 작동하는 곳에 쓰이면 좋을 것 같다.

let array = Observable.from([1, 2, 3, 3, 2, 1])

array
    .debounce(.milliseconds(1000), scheduler: MainScheduler.instance)
    .subscribe { print("debounce = \($0)") }
    .disposed(by: disposeBag)
    
// debounce = next(1)
// debounce = completed

 

+ Throttle

지정된 시간 동안 많은 이벤트가 발생해도 2개 이상의 요소가 방출되지 않아 스크롤에 사용하기 적합하다.
지정된 기간의 순차 기간 동안 Observable이 내보낸 첫 번째 항목과 최신 항목을 내보내는 Observable을 반환한다.
DueTime보다 짧은 시간에 두 개의 요소가 내보내지지 않도록 한다.

 

Distinct

Distinct

연달아 중복된 값이 들어올 때 무시한다.
아직 방출하지 않은 항목만 통과하도록 하여 Observable을 필터링한다.
일부 구현에는 두 항목을 "구분 (distinct)"로 간주하는 기준을 조정할 수 있는 변형이 있다.
어떤 연산는 구별성을 위해 항목을 바로 이전 항목과 비교만 하여 시퀀스에서 연속 중복 항목만 필터링하는 Observable이 있다.

let array = Observable.from([1, 2, 3, 3, 2, 1])

array
    .distinctUntilChanged()
    .subscribe { print("distinctUntilChanged = \($0)") }
    .disposed(by: disposeBag)

// distinctUntilChanged = next(1)
// distinctUntilChanged = next(2)
// distinctUntilChanged = next(3)
// distinctUntilChanged = next(2)
// distinctUntilChanged = next(1)
// distinctUntilChanged = completed

 

ElementAt

Element

Observable의 n번째에 있는 아이템만 방출한다.
Observable에서 내보낸 항목 순서로 지정된 인덱스 위치에 있는 항목을 가져와 해당 항목을 자체 방출로 내보낸다.

let array = Observable.from([1, 2, 3, 3, 2, 1])

array
    .element(at: 3)
    .subscribe { print("elementAt = \($0)")}
    .disposed(by: disposeBag)
    
// elementAt = next(3)
// elementAt = completed

 

Filter

Filter

Observable의 조건을 통과한 항목만 내보낸다.
함수 형식으로 지정한 항목만 해당 테스트를 통과하도록 허용하여 Observable 항목을 필터링한다.

let array = Observable.from([1, 2, 3, 3, 2, 1])

array
    .filter { $0 >= 2 }
    .subscribe { print("filter = \($0)")}
    .disposed(by: disposeBag)
    
// filter = next(2)
// filter = next(3)
// filter = next(3)
// filter = next(2)
// filter = completed

 

First

First

첫 번째 항목이나 특정 조건을 충족하는 첫 번째 항목을 배출한다.

일부 구현에서는 First가 Observable을 반환하는 필터링 연산자로 구현되지 않고 Observable이 해당 항목을 방출하는 시점에
특정 항목을 반환하는 차단 함수로 구현된다.
이러한 구현에서는 Filtering Observable을 사용하는 경우 Take(1) 이나 ElementAt(0)을 사용하는 것이 더 좋다.

일부 구현에서는 단일 연산자도 있다.
Observable이 단일 항목만 배출한다는 것을 보장하기 위해 종료까지 기다리는 점을 제외하면 첫 번째와 비슷하게 작동한다. 
그렇지 않으면 해당 항목을 배출하는 대신 오류로 종료된다.
Observable에서 첫 번째 항목을 가져올 뿐 아니라 항목이 존재하는지 확인하는 것에 사용할 수 있다. (Optional로 반환)

사용 여부는 항목의 단일 존재 여부와 최초의 값을 필요로 하는 분야로 생각한다.

let array = Observable.from([1, 2, 3, 3, 2, 1])
let error = Observable.from([])

array
    .first()
    .subscribe { print("first = \($0)") }
    .disposed(by: disposeBag)
    
error
    .first()
    .subscribe { print("first = \($0)")}
    .disposed(by: disposeBag)
    
// first = success(Optional(1))
// first = success(nil)

 

IgnoreElements

IgnoreElements

Observable 가능한 항목을 내보내지 않고 종료 알림을 미러링한다.
Observable에서 내보내는 모든 항목을 억제하지만 종료 알림(onError, onCompleted)은 변경되지 않고 통과하도록 허용한다.
Observable에서 내보내는 항목은 상관없지만 onError, onCompleted로 종료될 때 알림을 받으려면
ignoreElements 를 Observable에 적용하여 Observable의 onNext를 호출하지 않도록 할 수 있다.

let array = Observable.from([1, 2, 3, 3, 2, 1])

array
    .ignoreElements()
    .subscribe { print("ignoreElements = \($0)") }
    .disposed(by: disposeBag)
    
// ignoreElements = completed

 

Sample

Sample

주기적인 시간 간격 내 Observable에서 가장 최근에 방출된 항목을 내보낸다.
표본 연산자는 Observable 항목을 주기적으로 살펴보고 이전 표본 추출 이후 가장 최근에 방출된 항목을 내보낸다.

 

Skip

Skip

Observable의 첫 번째부터 n개 까지의 항목을 억제해서 배출한다.
Observable 항목에서 처음 n개 항목을 무시하고 그 다음 항목에만 참석할 수 있다.

let array = Observable.from([1, 2, 3, 3, 2, 1])

array
    .skip(3)
    .subscribe { print("skip = \($0)") }
    .disposed(by: disposeBag)
    
// skip = next(3)
// skip = next(2)
// skip = next(1)
// skip = completed

 

Take

Take

Skip과 반대로 첫 번째부터 n개 까지의 항목을 배출한다.
Observable에서 처음 n개 항목만 내보낸 다음 나머지는 무시하고 Take 연산자를 사용하여 Observable을 수정할 수 있다.

let array = Observable.from([1, 2, 3, 3, 2, 1])

array
    .take(3)
    .subscribe { print("take = \($0)") }
    .disposed(by: disposeBag)
    
// take = next(1)
// take = next(2)
// take = next(3)
// take = completed

 

TakeLast

TakeLast

Observable을 수정하여 최종 n개 항목만 내보내고 그 앞에 있는 항목은 무시할 수 있다.

let array = Observable.from([1, 2, 3, 3, 2, 1])

array
    .takeLast(2)
    .subscribe { print("takeLast = \($0)") }
    .disposed(by: disposeBag)
    
// takeLast = next(2)
// takeLast = next(1)
// takeLast = completed
반응형