全网整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:400-708-3566

RxSwift使用技巧之过滤操作详解

前言

在前面的基础之上接下来我会介绍一些常用的函数和实用技巧。首先,本文将会介绍那些用于对 next 事件进行过滤的操作。这些过滤操作类似于 Swift 标准库中的 filter 操作。它能在我们开始真正进行业务处理前先把那些不符合条件的过滤掉,而且这种函数式编程的范式也能开阔我们的思维。

Ignore 过滤

RxSwift 中最简单直接的过滤操作就是 ignoreElements 了。该操作会屏蔽所有的 next 事件,只会将注意力放在 error 和 completed 事件上。如下图所示,在整个生命周期中可观察对象的所有 next 都被过滤。

示例代码:

let strikes = PublishSubject<String>()
 
let disposeBag = DisposeBag()

strikes
 .ignoreElements()
 .subscribe { _ in
 print("You're out!")
 }
 .addDisposableTo(disposeBag)
 
strikes.onNext("X")
strikes.onNext("X")
strikes.onNext("X")
 
strikes.onCompleted()

/* 打印结果
You're out!
*/

不过相比于残暴的全部过滤,有时候我们可能只是需要过滤某些特定的事件。例如,我们可以通过 elementAt 对特定索引号 next 进行过滤。下图演示了只响应第二个 next 事件的 elementAt 操作。

与之相应的代码为:

let strikes = PublishSubject<String>()
 
let disposeBag = DisposeBag()
 
strikes
 .elementAt(2)
 .subscribe(onNext: { str in
 print(str)
 })
 .addDisposableTo(disposeBag)
 
strikes.onNext("1")
strikes.onNext("2")
strikes.onNext("3")
 
strikes.onCompleted()

/* 打印结果
3
*/

上面两个操作最后针对的 next 事件最多只会有一个,但是大多数时候我们其实需要筛选出一组符合条件的 next 事件。下图演示的就是使用 filter 筛选数据小于 3 的操作。

图示对应代码如下:

let strikes = PublishSubject<Int>()
 
let disposeBag = DisposeBag()
 
strikes
 .filter{ $0 < 3 }
 .subscribe(onNext: { num in
 print("\(num)")
 })
 .addDisposableTo(disposeBag)
 
strikes.onNext(1)
strikes.onNext(2)
strikes.onNext(3)
strikes.onNext(4)
strikes.onNext(5)
 
strikes.onCompleted()

/* 打印结果
1
2
*/

Skip 过滤

除了忽略操作外,另一个常见的过滤就是跳过操作了。在所有的跳过操作中,最简单的就属 skip 了。通过设定参数,我们就能和简单实现跳过指定个数的事件。例如,下图久演示跳过前两个事件的操作。

let strikes = PublishSubject<Int>()
 
let disposeBag = DisposeBag()
 
strikes
 .skip(2)
 .subscribe(onNext: { num in
 print("\(num)")
 })
 .addDisposableTo(disposeBag)
 
strikes.onNext(1)
strikes.onNext(2)
strikes.onNext(3)
strikes.onNext(4)
strikes.onNext(5)
 
strikes.onCompleted()

/* 打印结果
3
4
5
*/

当然除了跳过指定索引号的事件之外,我们依旧通过 skipWhile 我们能够实现类似 filter 类似的操作。只不过 filter 会过滤整个生命周期内的符合条件的事件,而 skipWhile 在找到第一个不符合跳过操作的事件之后就不再工作。例如,下图 skipWhile 的条件是数据为奇数就跳过,但是当数据 2 执行之后 数据 3 虽然也是奇数但是不会在跳过。所以严格意义上来说 skipWhile 可能有点歧义,实际是它会跳过所有符合条件的事件,直到找到第一个能执行事件后就不再生效。

下面是跳过偶数的 skipWhile 代码:

let strikes = PublishSubject<Int>()
 
let disposeBag = DisposeBag()
 
strikes
 .skipWhile{ num in
  num % 2 == 0
 }
 .subscribe(onNext: { num in
 print("\(num)")
 })
 .addDisposableTo(disposeBag)
 
strikes.onNext(2)
strikes.onNext(2)
strikes.onNext(3)
strikes.onNext(4)
strikes.onNext(5)
 
strikes.onCompleted()

/* 打印结果
3
4
5
*/

到目前为止,上面的过滤操作都是基于一些静态条件。如果现在你需要根据其它可观察对象实例的行为进行过滤判断怎么办呢?所以接下来将会介绍涉及多实例的动态判断,其中最常见的就是 skipUntil 操作。该操作过程如下图,上面两行表示可观察对象的生命周期而最下面的表示观察者,直到第二行的可观察对象发送数据后第三行的观察者才能接受到第一行发送的数据。

图示对应代码:

let strikes = PublishSubject<String>()
let trigger = PublishSubject<String>()
  
let disposeBag = DisposeBag()
 
strikes
 .skipUntil(trigger)
 .subscribe(onNext: { 
  print($0)
 })
 .addDisposableTo(disposeBag)
 
strikes.onNext("1")

trigger.onNext("X")

strikes.onNext("2")
strikes.onNext("3")
 
strikes.onCompleted()

/* 打印结果
2
3
*/

Take 过滤

这是一组与 Skip 相反的过滤操作。这组操作中最基础的操作为 take ,该操作的过程完全与 skip 相反。下图演示了 take(2) 操作的过程,它只会对前两个事件进行响应而忽略后面的事件。

上图对应代码:

let strikes = PublishSubject<String>()
  
let disposeBag = DisposeBag()
 
strikes
 .take(2)
 .subscribe(onNext: { 
  print($0)
 })
 .addDisposableTo(disposeBag)
 
strikes.onNext("1")
strikes.onNext("2")
strikes.onNext("3")
 
strikes.onCompleted()

/* 打印结果
1
2
*/

除此之外,skipWhile 也有对应的 Take 操作 takeWhile ,两者的代码结构几乎一致只不过前者是跳过操作而后者则是响应操作。不过这里我不准备介绍 takeWhile 操作(可以自己动手试下),而是介绍 takeWhile 变种 takeWhileWithIndex。其实函数名已经表明了该操作的主要功能,在 takeWhile 的基础上会加上索引 index 参数。因为有时候我们除了需要通过 value 进行过滤判断外,索引 index 也可能是一个判断维度。下图就展示了 takeWhileWithIndex 简单使用示例,对于 value 和 index 值小于 1 的事件全部跳过。

图示对应代码:

let strikes = PublishSubject<Int>()
  
let disposeBag = DisposeBag()
 
strikes
 .takeWhileWithIndex { integer, index in
  integer > 1 && index > 1
 }
 .subscribe(onNext: { 
  print( "\($0)")
 })
 .addDisposableTo(disposeBag)
 
strikes.onNext(1)
strikes.onNext(2)
strikes.onNext(3)
 
strikes.onCompleted()

/* 打印结果
3
*/

其实 Skip 组中同样存在与 takeWhileWithIndex 相对的 skipWhileWithIndex ,感兴趣可以自己检验一下。接下来我们介绍 Take 组中的最后一个操作 takeUntil 。同样地该操作是 skipUntil 的反操作,直到另一个实例对象触发后该实例对象的观察者才会停止响应。下图就是 takeUntil 操作的一个简单示例,作为观察者第三行会一直响应第一行可观察对象发送的数据,直到第二行对象触发后才停止。

对应代码:

let strikes = PublishSubject<String>()
let trigger = PublishSubject<String>()

let disposeBag = DisposeBag()
 
strikes
 .takeUntil(trigger)
 .subscribe(onNext: { 
  print($0)
 })
 .addDisposableTo(disposeBag)
 
strikes.onNext("1")
strikes.onNext("2")

trigger.onNext("X")

strikes.onNext("3")
 
strikes.onCompleted()

/* 打印结果
1
2
*/

Distinct 过滤

最后本文将介绍 Distinct 过滤操作 distinctUntilChanged 。对于观察者来说,有时可观察对象可能在某段时间内连续发生相同的数据。假设这些数据与 UI 相关的话,那么这里就存在不必要的刷新操作了。所以我们有必要对过滤这些连续的相同数据,减少不必要的响应操作。下图就是一个简单的示例,图中我们过滤掉了相同的后续数据,只会对第一个作出响应。

对应示例代码:

let strikes = PublishSubject<String>()

let disposeBag = DisposeBag()
 
strikes
 .distinctUntilChanged()
 .subscribe(onNext: { 
  print($0)
 })
 .addDisposableTo(disposeBag)
 
strikes.onNext("1")
strikes.onNext("2")
strikes.onNext("2")
strikes.onNext("3")
 
strikes.onCompleted()

/* 打印结果
1
2
3
*/

总结

本文在前面的基础上通过图示和代码介绍了主要的过滤操作。掌握好这些操作有利于我们最大化的发挥 RxSwift 功力。当然文中的代码都非常简单,所以我希望你在实际编程中不断磨练。

好了,以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对的支持。


# rxswift  # rxswift是什么  # 教程  # RxSwift实现替换delegate的方法示例  # 浅谈RxSwift 网络请求  # RxSwift学习教程之类型对象Subject详解  # RxSwift学习之Observable的新建、订阅及取消订阅  # RxSwift学习教程之基础篇  # RxSwift发送及订阅 Subjects、Variables代码示例  # 跳过  # 第一个  # 符合条件  # 将会  # 作了  # 会对  # 不符合  # 在前面  # 最简单  # 如下图  # 组中  # 都是  # 是一个  # 这是  # 只不过  # 也有  # 我不  # 好了  # 放在  # 我会 


相关文章: 如何通过老薛主机一键快速建站?  大学网站设计制作软件有哪些,如何将网站制作成自己app?  网站视频怎么制作,哪个网站可以免费收看好莱坞经典大片?  建站之星安装失败:服务器环境不兼容?  建站之星伪静态规则如何正确配置?  高性能网站服务器部署指南:稳定运行与安全配置优化方案  动图在线制作网站有哪些,滑动动图图集怎么做?  微信小程序制作网站有哪些,微信小程序需要做网站吗?  南平网站制作公司,2025年南平市事业单位报名时间?  深入理解Android中的xmlns:tools属性  简单实现Android验证码  临沂网站制作企业,临沂第三中学官方网站?  如何在香港服务器上快速搭建免备案网站?  上海网站制作开发公司,上海买房比较好的网站有哪些?  小视频制作网站有哪些,有什么看国内小视频的网站,求推荐?  MySQL查询结果复制到新表的方法(更新、插入)  详解jQuery中基本的动画方法  如何通过VPS搭建网站快速盈利?  制作旅游网站html,怎样注册旅游网站?  小说建站VPS选用指南:性能对比、配置优化与建站方案解析  道歉网站制作流程,世纪佳缘致歉小吴事件,相亲网站身份信息伪造该如何稽查?  如何在阿里云虚拟机上搭建网站?步骤解析与避坑指南  如何做网站制作流程,*游戏网站怎么搭建?  如何在Windows环境下新建FTP站点并设置权限?  表情包在线制作网站免费,表情包怎么弄?  活动邀请函制作网站有哪些,活动邀请函文案?  微信网站制作公司有哪些,民生银行办理公司开户怎么在微信网页上查询进度?  如何用虚拟主机快速搭建网站?详细步骤解析  如何快速使用云服务器搭建个人网站?  阿里云网站制作公司,阿里云快速搭建网站好用吗?  如何打造高效商业网站?建站目的决定转化率  赚钱网站制作软件,建一个网站怎样才能赚钱?是如何盈利的?  如何快速辨别茅台真假?关键步骤解析  如何在搬瓦工VPS快速搭建网站?  网站设计制作公司地址,网站建设比较好的公司都有哪些?  定制建站哪家更专业可靠?推荐榜单揭晓  海南网站制作公司有哪些,海口网是哪家的?  建站之星免费模板:自助建站系统与智能响应式一键生成  如何高效完成自助建站业务培训?  ppt制作免费网站有哪些,ppt模板免费下载网站?  魔毅自助建站系统:模板定制与SEO优化一键生成指南  Swift开发中switch语句值绑定模式  如何制作一个表白网站视频,关于勇敢表白的小标题?  电商网站制作多少钱一个,电子商务公司的网站制作费用计入什么科目?  安徽网站建设与外贸建站服务专业定制方案  再谈Python中的字符串与字符编码(推荐)  如何快速生成凡客建站的专业级图册?  潮流网站制作头像软件下载,适合母子的网名有哪些?  内部网站制作流程,如何建立公司内部网站?  微信h5制作网站有哪些,免费微信H5页面制作工具? 

您的项目需求

*请认真填写需求信息,我们会在24小时内与您取得联系。