iOS开发进阶 - RxSwift: Filter相关方法
source link: https://jesuslove.github.io/2019/03/27/iOS开发进阶-RxSwift-Filter相关方法/?amp%3Butm_medium=referral
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
万丈高楼平地起,前面两篇地基已经建好,现在开始第一层。
RxSwift 4.4
从本篇开始接下来几篇文章会详细学习 RxSwift
中 Operators
,作为 Rx
编程的基石,可以使用它来转换,处理和响应事件。
Operators
分为四个部分:
Filtering Operators Transforming Operators Combing Operators Time-Based Operators
接下来学习过滤相关的操作。
Filtering Operators
过滤操作分为四类:
分类 主要方法 说明Ignoring Operators
ignoreElements
elementAt
filter
用于忽略一些元素
Skipping Operators
skip
skipWhile
skipUntil
Taking Operators
take
takeWhile
takeUntil
Distinct Operators
distinctUntilChange
distinctUntilChanged(_:)
从整体上了解要学习的内容,接下来详细分析各个操作作用,特点及区别联系。
Ignoring Operators
ignoreElements
特点:忽略所有的 .next
事件元素,允许终止事件通过。如: .completed
和 .error
。是不是应该想起来什么? ignoreElements
实际上返回一个 Completable
。
①:表示源序列,可以被订阅
②:表示操作及参数
③:订阅
实例代码:
/// 1. ignoreElements : 忽略所有的 .next 事件元素,允许停止事件通过,如 .completed 和 .error. /// 也许会发现:ignoreElements 实际上返回一个 Completable example(of: "ignoreElements") { // 1. 创建 subject let strikes = PublishSubject<String>() let disposeBag = DisposeBag() // 2. 添加订阅 strikes .ignoreElements() // 忽略所有元素 .subscribe{_ in print("You are out!") } .disposed(by: disposeBag) strikes.onNext("X") // 无输出 strikes.onNext("Y") // 无输出 strikes.onCompleted() // 输出 You are out! }
elementAt
特点: 获取指定位置的元素。只要获取到指定位置的元素,订阅就终止。
示例代码:
/// 2. elementAt : 获取指定位置的元素。 /// 只要获取到指定位置的元素,订阅就终止。 example(of: "elementAt") { let strikes = PublishSubject<String>() let bag = DisposeBag() strikes .elementAt(2) // 获取序列中 index = 2 的元素 .subscribe(onNext: { element in print("\(element) - You are out!") }) .disposed(by: bag) strikes.onNext("X") // 无输出 strikes.onNext("Y") // 无输出 strikes.onNext("Z") // index = 2 输出 // 输出:Z - You are out! }
filter
特点: ignoreElement
和 elementAt
过滤序列元素。有时不针对全部或单个元素操作。 filter
提供了一个闭包,针对所有的元素,只要满足添加就可以输出。
示例代码:
/// 3. ignoreElement 和 elementAt 过滤序列元素。有时不针对全部或单个元素操作。 /// filter 提供了一个闭包,针对所有的元素,只要满足添加就可以输出。 example(of: "filter") { let bag = DisposeBag() // 1. 创建一个序列 Observable.of(1, 2, 3, 4, 5, 6) .filter{ $0 % 2 == 0} // 2. 过滤偶数 .subscribe(onNext: { // 3. 订阅 print($0) }) .disposed(by: bag) // 输出: 2 4 6 }
Transforming Operators
skip
特点: 跳过指定数量的元素。
示例代码:
/// 1. skip() : 跳过指定数量的元素 example(of: "skip") { let bag = DisposeBag() // 1. 序列 Observable.of("A", "B", "C", "D", "E", "F") .skip(3) // 2. 跳过三个元素 .subscribe( onNext: { // 3. 订阅 print($0) }) .disposed(by: bag) // 输出: D E F }
skipWhile
/// 2. skipWhile : 像 skip 一样决定哪些元素被忽略。 /// skipWhile 只跳过元素,直到第一个元素被允许通过,然后所有剩余的元素都被允许通过。 /// 闭包 返回 true 对应的元素将被忽略;返回 false 对应的元素通过。 /// 与 filter 操作相反。 example(of: "skipWhile") { let bag = DisposeBag() Observable.of(2, 2, 3, 4, 4) // 1. 序列 .skipWhile { $0 % 2 == 0} // 2. 跳过 开始时的 偶数 .subscribe(onNext: { print($0) }) .disposed(by: bag) // 输出: 3 4 4 }
skipUntil
/// 以上都是静态的条件过滤元素,如果想基于其他序列动态过滤元素怎么办? /// 3. skipUntil : 它将保持跳过原序列所有元素,直到触发序列发射 .next 事件,开始输出后续元素。 example(of: "skipUntil") { let bag = DisposeBag() // 1. 一个源序列,一个触发序列 let subject = PublishSubject<String>() let trigger = PublishSubject<String>() // 2. subject .skipUntil(trigger) // 直到 trigger 序列有 .next 事件 .subscribe(onNext: { print($0) }) .disposed(by: bag) subject.onNext("A") subject.onNext("B") // 未输出 trigger.onNext("X") // 触发 subject.onNext("C") // 输出:C }
Taking Operators
take
/// Taking 是与 Skipping 相反的操作。 /// 1. take: 获取几个元素 example(of: "take") { let bag = DisposeBag() Observable.of(4, 5, 6, 7, 8, 9) .take(3) // 获取三个元素 .subscribe(onNext: { print($0) }) .disposed(by: bag) // 输出: 4 5 6 }
takeWhile
/// 2. takeWhile: 与 skipWhile 类似,不同点是用 taking 代替 skipping example(of: "takeWhile") { let bag = DisposeBag() Observable.of(2, 2, 4, 4, 6, 6) .enumerated() // 1. 获取元组包含 index 和 element .takeWhile({ index, integer in // 2. 直到条件不成立停止 integer % 2 == 0 && index < 3 }) .map { $0.element } // 3. 获取元素,生成只包含元素的序列 .subscribe(onNext: { // 4. 订阅输出 print($0) }) .disposed(by: bag) // 输出: 2 2 4 }
takeUntil
/// 3. takeUntil: 与 skipUntil 类似 /// 持续获取源序列中元素,直到触发序列发送 .next 事件。 example(of: "takeUntil") { let bag = DisposeBag() // 1. let subject = PublishSubject<String>() let trigger = PublishSubject<String>() // 2. subject .takeUntil(trigger) .subscribe(onNext: { print($0) }) .disposed(by: bag) // 3. subject.onNext("A") subject.onNext("B") trigger.onNext("1") // 触发序列终止源序列 subject.onNext("C") // 输出:A B // 思考:是不是可以通过 takeUntil 监控 VC 的销毁。 }
Distinct Operators
distinctUntilChanged
/// 1. distinctUntilChanged : 阻止下一个重复元素 /// 只阻止相邻重复元素。 example(of: "distinctUntilChanged") { let bag = DisposeBag() Observable.of("A", "A", "B", "B", "A") .distinctUntilChanged() .subscribe(onNext: { print($0) }) .disposed(by: bag) // 输出:A B A }
distinctUntilChanged(_:)
/// 2. distinctUntilChanged(_:) 自定义比较 example(of: "distinctUntilChanged(_:)") { let bag = DisposeBag() // 1 let formatter = NumberFormatter() formatter.numberStyle = .spellOut // 朗读形式,英文,例如:110 ==> ["one", "hundred", "ten"] // 2. 序列 Observable<NSNumber>.of(10, 110, 20, 200, 210, 310) // 3 .distinctUntilChanged { a, b in guard let aWords = formatter.string(from: a)?.components(separatedBy: " "), let bWords = formatter.string(from: b)?.components(separatedBy: " ") else {return false} print(aWords, bWords) var containsMatch = false for aWord in aWords where bWords.contains(aWord) { containsMatch = true break } return containsMatch /* 第一次:["ten"] ["one", "hundred", "ten"] ==> true, 跳过 110 第二次:["ten"] ["twenty"] ==> false 第三次:["twenty"] ["two", "hundred"] ==> false 第四次:["two", "hundred"] ["two", "hundred", "ten"] ==> true,跳过 210 第五次:["two", "hundred"] ["three", "hundred", "ten"] ==> true, 跳过 310 */ } // 订阅 .subscribe(onNext: { print($0) }) .disposed(by: bag) }
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK