(九)RxSwift之过滤操作符(filter)

3,408 阅读3分钟

过滤/筛选 被观察者Observable发送的事件或观察者Observer接收的事件

操作符 描述
filter 通过过滤条件,发送符合条件的元素
distinctUntilChanged 去掉重复的元素
elementAt 发出指定索引处的元素
debounce 消抖,过滤掉高频产生的元素,持续的触发一个函数,它结束后过一段时间只执行一次
throttle 节流,过滤掉高频产生的元素,持续的触发一个函数,它在一定的时间间隔后再触发
ignoreElements 忽略掉所有的元素,只发出 error 或 completed 事件
single 只发出满足条件的第一个元素,多了将抛出异常
take 从 Observable 中发出头部 n 个元素
takeLast 从 Observable 中发出尾部 n 个元素
takeWhile 直到某个元素的判定为 false。此时, Observable 将立即终止
takeUntil 直到参考可观察序列发出元素,忽略掉在第二个 Observable 产生事件后发出的那部分元素
skip 跳过 Observable 中头 n 个元素
skipWhile 跳过 Observable 中头几个元素,直到元素的判定为否
skipUntil 跳过 Observable 中头几个元素,直到另一个 Observable 发出一个元素
Sample 第二个序列发出元素,就取第一个原序列的最后一个
  • filter

仅从满足指定条件的可观察序列中发出那些元素

示例:

Observable.of(1, 2, 3, 4, 5, 6, 7, 8 , 9, 0)
    .filter{ $0 % 2 == 0}
    .subscribe(onNext: {print($0, terminator: " ")})
    .disposed(by: disposeBag)

//输出:2 4 6 8 0
  • distinctUntilChanged

抑制可观察序列发出的顺序重复元素(不同的直到改变)

示例:

Observable.of("1", "2", "3", "3", "4", "4")
    .distinctUntilChanged()
    .subscribe(onNext: {print($0, terminator: " ")})
    .disposed(by: disposeBag)
//输出:1 2 3 4
  • elementAt

仅在可观察序列发出的所有元素的指定索引处发出元素

示例:

Observable.of("M", "a", "X", "i", "a", "o", "L", "i", "a", "0")
.elementAt(3)
.subscribe(onNext: {print($0, terminator: " ")})
.disposed(by: disposeBag)
//输出:i
  • debounce 消抖

过滤掉高频产生的元素,如果一个函数持续地触发,那么只在它结束后过一段时间只执行一次。

示例:

let subject = PublishSubject<Int>()

subject.debounce(DispatchTimeInterval.seconds(2), scheduler: MainScheduler())
    .subscribe(onNext: { print($0, terminator:" ") })
        .disposed(by: disposeBag)

subject.onNext(1)
subject.onNext(2)
subject.onNext(3)
subject.onNext(4)

delay(1) {
    subject.onNext(5)
}
delay(4) {
    subject.onNext(6)
}

//5 6
//2秒内只接受最新的元素
  • throttle 节流

过滤掉高频产生的元素,如果一个函数持续的,频繁地触发,那么让它在一定的时间间隔后再触发。 示例:

let subject = PublishSubject<Int>()

subject.throttle(DispatchTimeInterval.seconds(2), scheduler: MainScheduler())
       .subscribe(onNext: { print($0, terminator:" ") })
       .disposed(by: disposeBag)

subject.onNext(1)
subject.onNext(2)
subject.onNext(3)
subject.onNext(4)

delay(1) {
   subject.onNext(5)
}

delay(2) {
    subject.onNext(6)
}

delay(3) {
    subject.onNext(7)
}
//输出:1 5 7

为了避免某个『事件』在『一个较短的时间段内』内连续被触发从而引起的其对应的『事件处理函数』, 二者的根本的区别在于 throttle 保证了在每个 delta T 内至少执行一次,而 debounce 没有这样的保证。

  • ignoreElements

该操作符可以忽略掉所有的元素,只发出 error 或 completed 事件,如果我们并不关心 Observable 的任何元素,只想知道 Observable 在什么时候终止,可以使用 ignoreElements 操作符。

示例:

Observable.of(1, 2, 3, 4)
.ignoreElements()
.subscribe{
    print($0)
}
.disposed(by: disposeBag)

//输出:completed
  • single

只发出可观察序列发出的第一个元素(或满足条件的第一个元素)。如果可观察序列发出多个元素,将抛出一个错误。

示例:

Observable.of("sand", "MaXiaoliao")
    .single()
    .subscribe(onNext: { print($0) })
    .disposed(by: disposeBag)
//输出:
//sand
//Unhandled error happened: Sequence contains more than one element. subscription called from:
Observable.of("sand", "MaXiaoliao")
    .single{ $0 == "sand"}
    .subscribe(onNext: { print($0) })
    .disposed(by: disposeBag)
//输出:sand
  • take

只从一个可观察序列的开始发出指定数量的元素。 上面signal只有一个序列 在实际开发会受到局限 这里引出 take 想几个就几个。

示例:

Observable.of("apple", "orange", "banana", "peach")
    .take(2)
    .subscribe(onNext: { print($0, terminator: " ") })
    .disposed(by: disposeBag)
//输出:apple orange
  • takeLast

只发出尾部 n 个元素。并且忽略掉前面的元素。

示例:

 Observable.of("apple", "orange", "banana", "peach")
    .takeLast(3)
    .subscribe(onNext: { print($0, terminator: " ") })
    .disposed(by: disposeBag)
//输出:orange banana peach
  • takeWhile

源 Observable 直到某个元素的判定为 false。此时,这个镜像的 Observable 将立即终止。

示例:

 Observable.of("apple", "banana", "aorange", "peach")
    .takeWhile { $0 .hasPrefix("a") }
    .subscribe(onNext: { print($0, terminator: " ") })
    .disposed(by: disposeBag)
 //输出:apple
  • takeUntil

从源可观察序列发出元素,直到参考可观察序列发出元素,忽略掉在第二个 Observable 产生事件后发出的那部分元素,这个要重点,应用非常频繁 比如我页面销毁了,就不能获取值了(cell重用运用)

示例:

let sourceSequence = PublishSubject<String>()
let referenceSequence = PublishSubject<String>()

sourceSequence
    .takeUntil(referenceSequence)
    .subscribe{ print($0, terminator: " ") }
    .disposed(by: disposeBag)

sourceSequence.onNext("apple")
sourceSequence.onNext("orange")
sourceSequence.onNext("banana")
referenceSequence.onNext("fruit")
sourceSequence.onNext("tea")
sourceSequence.onNext("Black tea")
//输出: next(apple) next(orange) next(banana) completed
  • skip

跳过 Observable 中头 n 个元素,只关注后面的元素 ,这个要重点,应用非常频繁 不用解释 textfiled 都会有默认序列产生

示例:

Observable.of(1, 2, 3, 4, 5, 6)
    .skip(2)
    .subscribe(onNext: { print($0, terminator: " ") })
    .disposed(by: disposeBag)
//输出:3 4 5 6
  • skipWhile

跳过 Observable 中头几个元素,直到元素的判定为否

示例:

 Observable.of(1, 5, 3, 4, 2, 6)
    .skipWhile { $0 < 4 }
    .subscribe(onNext: { print($0, terminator: " ") })
    .disposed(by: disposeBag)
//输出:5 3 4 2 6 
  • skipUntil

跳过 Observable 中头几个元素,直到另一个 Observable 发出一个元素

示例:

let sourceSeq = PublishSubject<String>()
let referenceSeq = PublishSubject<String>()

sourceSeq
.skipUntil(referenceSeq)
.subscribe(onNext: { print($0, terminator: " ") })
.disposed(by: disposeBag)

//没有条件命令 下面走不了
sourceSeq.onNext("apple")
sourceSeq.onNext("orange")
sourceSeq.onNext("banana")
referenceSeq.onNext("fruit")
sourceSeq.onNext("tea")
sourceSeq.onNext("BlackTea")
//输入:tea BlackTea
  • sample

sample 操作符将不定期的对源 Observable 进行取样操作。通过第二个 Observable 来控制取样时机。一旦第二个 Observable 发出一个元素,就从源 Observable 中取出最后产生的元素。

示例:

let source = PublishSubject<Int>()
let notifier = PublishSubject<String>()

source
    .sample(notifier)
    .subscribe(onNext: { print($0, terminator:" ") })
    .disposed(by: disposeBag)

source.onNext(1)

//让源序列接收消息
notifier.onNext("A")

source.onNext(2)

//让源序列接收接收消息
notifier.onNext("B")
notifier.onNext("C")

source.onNext(3)
source.onNext(4)
 
//让源序列接收接收消息
notifier.onNext("D")
 
source.onNext(5)
 
//让源序列接收接收消息
notifier.onCompleted()

//输出:1 2 4 5