skip 연산자는 특정 요소를 무시하는 연산자이다.
skip
skip연산자는 정수를 파라미터로 받는다. 옵저버블이 방출하는 요소중에서 지정된 수만큼 무시한 다음에 이후에 방출되는 요소만 구독자로 전달한다.
let disposeBag = DisposeBag()
let numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Observable.from(numbers)
.skip(3)
.subscribe{ print($0)}
//next(4)
//next(5)
//next(6)
//next(7)
//next(8)
//next(9)
//next(10)
//completed
결과를 보면 4부터 방출된다. 지정한 3개의 요소 1, 2, 3을 무시하고 다음부터 방출한다.
코딩을 하다보면 skip연산자의 파라미터 값을 인덱스로 혼동하는 경우가 많다. 인덱스가 아닌 개수다.
skipWhile
skipWhile은 클로저를 파라미터로 받는다. 이 클로저는 필터 연산자와 만찬가지로 predicate로 사용되고 클로저에서 true를 리턴하는 동안 방출되는 요소를 무시한다.
클로저에서 false를 리턴하면 그때부터 요소를 방출하고, 그 후 부터는 조건에 관계없이 모든 요소를 방출한다.
연산자는 방출되는 요소를 포함한 옵저버블을 리턴한다.
let numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Observable.from(numbers)
.skip(while: {
return !$0.isMultiple(of: 2)
})
.subscribe{print($0)}
//next(2)
//next(3)
//next(4)
//next(5)
//next(6)
//next(7)
//next(8)
//next(9)
//next(10)
//completed
결과를 보면 2부터 방출하고 있다. 2가 전달되면 클로저가 false를 리턴하고 이때무터 이어지는 모든 요소가 방출된다.
다시말해 구독자로 전달된다.
filter연산자와 달리 클로저가 false를 리턴한 다음에는 더이상 조건을 확인하지 않는다.
skipUntil
옵저버블 타입을 파라미터로 받는다.
다시말해 다른 옵저버블을 파라미터로 받는다. 이 옵저버블이 NextEvent를 전달하기 전까지 원본 옵저버블이 전달하는 요소를 무시한다.
특징 때문에 파라미터로 전달하는 옵저버블을 트리거라고 부르기도 한다.
let subject = PublishSubject<Int>()
let trigger = PublishSubject<Int>()
subject.skip(until: trigger)
.subscribe{ print($0) }
.disposed(by: disposeBag)
subject.onNext(1)
아직 트리거가 요소를 방출하지 않았기 때문에 서브젝트는 요소를 방출하지 않는다.
let subject = PublishSubject<Int>()
let trigger = PublishSubject<Int>()
subject.skip(until: trigger)
.subscribe{ print($0) }
.disposed(by: disposeBag)
subject.onNext(1)
trigger.onNext(0)
이번엔 트리거가 요소를 방출한다.
서브젝트가 이전에 전달했던 요소는 여전히 구독자로 전달되지 않고있다. skipuntil은 트리거가 요소를 방출한 뒤로부터 원본 옵저버블에서 방출되는 요소들을 구독자로 전달한다.
let subject = PublishSubject<Int>()
let trigger = PublishSubject<Int>()
subject.skip(until: trigger)
.subscribe{ print($0) }
.disposed(by: disposeBag)
subject.onNext(1)
trigger.onNext(0)
subject.onNext(2)
//next(2)
skipduration
let o = Observable<Int>.interval(.seconds(1), scheduler: MainScheduler.instance)
o.take(10)
.subscribe { print($0) }
.disposed(by: disposeBag)
//1초에 하나씩 0~9까지가 nextEvent로 방출되고
//CompletedEvent가 방출된다
.skip(duration: RxTimeInterval>, scheduler: SchedulerType)
skipduration는 2개의 파라미터를 받는다. 첫 번째파라미터는 옵저버블이 방출하는 이벤트를 무시하는 시간이다.
두번째 파라미터는 타이머를 실행할 스케쥴러이다.
이 연산자는 옵저버블이 이벤트 방출을 시작한 시점부터 첫 번째 파라미터로 전달한 시간동안 옵저버블이 방출하는 모든 이벤트를 무시한다.
o.take(10)
.skip(.seconds(3), scheduler: MainScheduler.instance)
.subscribe { print($0) }
.disposed(by: disposeBag)
이렇게 두면 옵저버블이 방출하는 이벤트를 3초동안 무시한다. 그래서 실행 후 3초뒤에 2...9completed가 된다
옵저버블이 0부터 방출하고 있으니 이론적으론 3부터 방출되어야 하는데, 2부터 방출이 된다.
이렇게 되는 이유는 시간을 처리할 때 오차가 발생하기 때문이다.
1초마다 방출하도록 지정했지만 1초마다 정확히 방출하는게 아니고 ms단위의 오차가 발생한다.
또한 무시하는 시간을 3초로 지정했지만 정확히 3초가 아니고 약간의 오차가 발생한다.