Skip to content

Latest commit

 

History

History
318 lines (225 loc) · 6.62 KB

7.2、过滤操作符.md

File metadata and controls

318 lines (225 loc) · 6.62 KB

过滤操作符

过滤操作指的是从源 Observable 中选择特定的数据发送。

  • 通过判定条件过滤出一些元素:filter
  • 仅仅发出第几个元素:elementAt
  • 跳过头几个元素
    • 跳过头几个元素:skip
    • 跳过 Observable 中头几个元素,直到另一个 Observable 发出一个元素 :skipUntil
  • 只取头几个元素
    • 只取头几个满足判定的元素:takeWhile,takeWhileWithIndex
    • 只取某段时间内产生的头几个元素:take
    • 只取头几个元素直到另一个observable发出一个元素:takeUntil
    • 仅仅发出尾部几个元素:takeLast
  • 周期性对observable抽样:sample
  • 发出那些元素,这些元素产生后的特定时间内没有新元素产生:debounce
  • 直到元素的值发生变化才发出新的元素:distinctUntilChanged

1、filter

该操作符就是用来过滤掉某些不符合要求的事件。 filter

Observable.of(2, 30, 22, 5, 60, 3, 40 ,9)
.filter {
$0 > 10
}
.subscribe(onNext: { print($0) })
.disposed(by: disposeBag)

结果

30
22
60
40

2、elementAt

该方法实现只处理在指定位置的事件

elementat

Observable.of("🐱", "🐰", "🐶", "🐸", "🐷", "🐵")
.elementAt(2)
.subscribe(onNext: { print($0) })
.disposed(by: disposeBag)

打印结果

🐶

3.1、skip

跳过Observable的头几个元素 skip

Observable.of("🐱", "🐰", "🐶", "🐸", "🐷", "🐵")
.skip(2)
.subscribe(onNext: { print($0) })
.disposed(by: disposeBag)

打印结果

🐶
🐸
🐷
🐵

3.2、skipUntil

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

skipUntil

let sourceSequence1 = PublishSubject<Any>()
let referenceSequence1 = PublishSubject<Any>()

sourceSequence1

.skipUntil(referenceSequence1)

.subscribe(onNext: { print($0,"->skipUntil") })

.disposed(by: disposeBag)

sourceSequence1.onNext("🐱")

sourceSequence1.onNext("🐰")

sourceSequence1.onNext("🐶")

referenceSequence1.onNext("🔴")

sourceSequence1.onNext("🐸")

sourceSequence1.onNext("🐷")

sourceSequence1.onNext("🐵")

打印结果

🐸 ->skipUntil
🐷 ->skipUntil
🐵 ->skipUntil

take

仅仅从observable中发出头n个元素 take

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

打印结果

1
2

takeLast

仅仅从observable中发出尾部的n个元素

takeLast

takeUntil

除了订阅源 Observable 外,通过 takeUntil 方法我们还可以监视另外一个 Observable, 即 notifier

如果 notifier 发出值或 complete 通知,那么源 Observable 便自动完成,停止发送事件。

takeUntil

let disposeBag = DisposeBag()

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

source
.takeUntil(notifier)
.subscribe(onNext: { print($0) })
.disposed(by: disposeBag)

source.onNext("1")
source.onNext("2")


//停止接收消息
notifier.onNext("0")

source.onNext("3")
source.onNext("4")

打印结果

1
2

takeWhile

该方法依次判断 Observable 序列的每一个值是否满足给定的条件。 当第一个不满足条件的值出现时,它便自动完成。

takeWhile

Observable.of(2, 3, 4, 5, 6)
.takeWhile { $0 < 4 }
.subscribe(onNext: { print($0) })
.disposed(by: disposeBag)

打印结果

2
3

sample

Sample 除了订阅源 Observable 外,还可以监视另外一个 Observable, 即 notifier 。

每当收到 notifier 事件,就会从源序列取一个最新的事件并发送。而如果两次 notifier 事件之间没有源序列的事件,则不发送值。

Sample

let source = PublishSubject<Int>()
let notifier = PublishSubject<String>()
source
.sample(notifier)
.subscribe(onNext: { print($0) })
.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)
source.onNext(6)
//让源序列接收接收消息
notifier.onCompleted()

打印结果

1
2
4
6

debounce

debounce 操作符可以用来过滤掉高频产生的元素,它只会发出这种元素:该元素产生后,一段时间内没有新元素产生。 换句话说就是,队列中的元素如果和下一个元素的间隔小于了指定的时间间隔,那么这个元素将被过滤掉。 debounce 常用在用户输入的时候,不需要每个字母敲进去都发送一个事件,而是稍等一下取最后一个事件。

debounce

//定义好每个事件里的值以及发送的时间
let times = [
[ "value": 1, "time": 0.1 ],
[ "value": 2, "time": 1.1 ],
[ "value": 3, "time": 1.2 ],
[ "value": 4, "time": 1.2 ],
[ "value": 5, "time": 1.4 ],
[ "value": 6, "time": 2.1 ]
]

//生成对应的 Observable 序列并订阅
Observable.from(times)
.flatMap { item in
return Observable.of(Int(item["value"]!))
.delaySubscription(Double(item["time"]!),
scheduler: MainScheduler.instance)
}
.debounce(0.5, scheduler: MainScheduler.instance) //只发出与下一个间隔超过0.5秒的元素
.subscribe(onNext: { print($0) })
.disposed(by: disposeBag)

}

打印结果

1
2
4
6

distinctUntilChanged

阻止observable发出相同的元素,如果前一个元素和后一个元素是相同的,那么这个元素将不会被发出来,仅仅判断相邻的两个元素

Observable.of("1","2","1","1","2","2","0")
.distinctUntilChanged()
.subscribe(onNext: {print($0)})
.disposed(by: disposeBag)

打印结果

1
2
1
2
0