filter는 들어오는 데이터 중에서 필요한 데이터는 취하고 필요하지 않는 데이터는 제외시키는 것으로 많이 알고 있다. 이번에는 RxSwift에서 이런 필터링하는 연산에 대해서 정리해보려고 한다.
ignoreElements()
를 적용하게 되면 구독자에게 이벤트가 넘어가지 않는다. 하지만 점선으로 종료되는 시점은 구독자에게 넘어가는 것을 볼 수 있다. let observer = Observable.of(1,2,3)
let disposeBag = DisposeBag()
observer.ignoreElements()
.subscribe({ (value) in
print(value)
})
.disposed(by: disposeBag)
// completed
위 코드에서도 마찬가지로 (1,2,3) 요소를 출력하려고 했지만 아무것도 출력이 되지 않았다.
즉, 모든 .next
이벤트는 무시하고 .completed
나 .error
이벤트만 허용한다
let observer = Observable.of(1,2,3)
let disposeBag = DisposeBag()
observer.elementAt(0)
.subscribe({ (value) in
print(value)
})
.disposed(by: disposeBag)
// next(1)
// completed
위 코드에서 (1,2,3) 요소들을 출력하려고 하는데 .elementAt(index)
를 사용해서 해당 index에 해당하는 값을 구독자에게 방출한다. 그래서 위 코드에서는 0번째 인덱스에 해당하는 값인 1이 넘어왔다.
let observer = Observable.of(1,2,3,4,5,6,7,8,9,10)
let disposeBag = DisposeBag()
observer.filter({ (value) -> Bool in
value % 2 == 0
})
.subscribe({ (value) in
print(value)
})
.disposed(by: disposeBag)
// next(2)
// next(4)
// next(6)
// next(8)
// next(10)
// completed
위 코드를 보면 1~10까지의 요소 중 `.filter`를 통해서 나머지가 0인 요소만 구독자에게 넘기는 방식을 사용해서 짝수 요소만 출력이 된 모습을 볼 수 있다.
## Skipping Operators
1. .skip
이 연산자는 첫 번째 요소부터 n개의 요소를 건너뛰고 싶을 때 사용한다.
```swift
let observer = Observable.of(1,2,3,4,5,6,7,8,9,10)
let disposeBag = DisposeBag()
observer.skip(5)
.subscribe({ (value) in
print(value)
})
.disposed(by: disposeBag)
// next(6)
// next(7)
// next(8)
// next(9)
// next(10)
// completed
위 코드에서 보면 .skip(5)
를 사용해서 1~10의 요소에서 첫 요소(1)부터 5개의 요소(5까지)를 건너 뛴 6부터 출력되는 모습을 볼 수 있습니다.
.skip
은 단순히 몇 개의 요소를 건너뛰었다면 .skipWhile
은 filter처럼 해당 수식에let observer = Observable.of(2,2,3,4,2,5,6)
let disposeBag = DisposeBag()
observer.skipWhile({ (value) -> Bool in
value % 2 == 0
})
.subscribe({ (value) in
print(value)
})
.disposed(by: disposeBag)
// next(3)
// next(4)
// next(2)
// next(5)
// next(6)
// completed
(2,2,3,4,2,5,6) 요소에서skipWhile({ (value) -> Bool in value % 2 == 0 })
수식을 만나게 되면 앞에 2개의 2는 true이기 때문에 skip이 이루어지고 3은 false다. 그래서 방출이 되고 이 이후로는 true여도 방출이 돼서 출력이 된다.
let disposebag = DisposeBag()
let subject = PublishSubject<Int>()
let skipSubject = PublishSubject<Int>()
subject.skipUntil(skipSubject)
.subscribe(onNext: {
print($0)
})
.disposed(by: disposebag)
subject.onNext(1)
subject.onNext(2)
skipSubject.onNext(10)
subject.onNext(3)
// 3
skipSubject가 onNext
하기 전에 방출한 1,2 이벤트는 방출되지 않고 그 이후로 방출한 3 이벤트만 출력된 모습을 볼 수 있다.
let disposebag = DisposeBag()
let observer = Observable.of(1,2,3,4,5)
observer.take(3)
.subscribe({ (value) in
print(value)
})
.disposed(by: disposebag)
// next(1)
// next(2)
// next(3)
// completed
(1,2,3,4,5) 요소 중에서 .take
연산자를 통해서 3개의 요소만 가져온다고 해서 (1,2,3) 요소만 출력이 된 모습을 볼 수 있습니다.
let disposebag = DisposeBag()
let observer = Observable.of(2,4,3,5,6)
observer.takeWhile({ (value) -> Bool in
value % 2 == 0
})
.subscribe({ (value) in
print(value)
})
.disposed(by: disposebag)
// next(2)
// next(4)
// completed
주어진 수식에 true인 값을 출력하고 false인 값부터 출력하지 않는다.
let disposebag = DisposeBag()
let observer = Observable.of(2,4,3,5,6)
observer
.enumerated()
.takeWhile({ index, value -> Bool in
value % 2 == 0
})
.subscribe({ (value) in
print(value)
})
.disposed(by: disposebag)
// next((index: 0, element: 2))
// next((index: 1, element: 4))
completed
takeWhile에서의 출력 값을 인덱스와 함께 출력한 모습을 볼 수 있다.
.skipUntil
과 반대로 수행한다.let disposebag = DisposeBag()
let subject = PublishSubject<Int>()
let takeSubject = PublishSubject<Int>()
subject.takeUntil(takeSubject)
.subscribe(onNext: {
print($0)
})
.disposed(by: disposebag)
subject.onNext(1)
subject.onNext(2)
takeSubject.onNext(10)
subject.onNext(3)
// 1
// 2
위 코드처럼 .skipUntil
과 반대로 다른 observer가 이벤트를 방출하기 전까지 방출된 이벤트를 구독자에게 전달한다.
let disposebag = DisposeBag()
Observable.of(1,2,3,3,4)
.distinctUntilChanged()
.subscribe(onNext: {
print($0)
})
.disposed(by: disposebag)
// 1
// 2
// 3
// 4
출력에서 중복되는 3요소를 1번만 출력한 모습을 볼 수 있다. 또한 이 안에다가 수식을 넣어서 커스텀된 연산자를 만들 수 있다.