RxSwift 中7个有用的过滤运算符

原文:7 USEFUL FILTERING OPERATORS IN RXSWIFT

使用 RxSwift 几个月后,我可以有把握地说过滤是一个关键功能,它为我节省了大量代码。要知道何时使用哪些过滤运算符,需要有一个基本的概述,所以让我们看看这个库提供的 7 个我最喜欢的过滤运算符。

RxSwift 是流行的 ReactiveX 库的 Swift 实现。当涉及到过滤数据时,这个库可以很好地帮助你。它有各种运算符,允许你以各种方式过滤数据,以便你只传递你希望订阅者接收的数据。

本质上,这些运算符是对 next 事件的条件约束。这意味着可观察对象发出的所有 next 事件元素都会通过你指定的运算符。每个元素都需要满足操作符的要求 - 如果不满足,它们将被丢弃。

大多数运算符对可观察序列进行操作并返回一个可观察序列。这样,我们就能够链接这些运算符,因为下一个运算符将前一个运算符的输出作为输入。

需要注意的一点是:你无法使用这些运算符过滤停止事件(stop-events),即完成事件(completed-events)和错误事件(error-events)。过滤运算符仅对 next 事件进行操作。

1. filter()

列表中的第一个运算符是 filter 运算符。

该运算符的工作方式是过滤运算符将谓词作为参数。谓词作为条件约束,可观察对象发出的每个元素都必须满足该条件约束。这样,谓词将应用于所有元素,并确定每个元素是否允许通过订阅者。

看看这个弹珠图:

在这种情况下,filter() 将只允许值大于 10 的元素通过。这些元素将到达下一个运算符,而其余元素将被删除。

现在,让我们看一个代码示例:

swift 复制代码
import RxSwift

let bestSellingAlbums = [
  (title: "Thriller", salesInMillions: 93),
  (title: "Eagles: Their Greatest Hits 1971-1975", salesInMillions: 41),
  (title: "Hotel California", salesInMillions: 32),
  (title: "Come on Over", salesInMillions: 29),
  (title: "Led Zeppelin IV", salesInMillions: 29),
  (title: "The Bodyguard Soundtrack", salesInMillions: 28),
  (title: "Rumours", salesInMillions: 27),
  (title: "Back in Black", salesInMillions: 26),
  (title: "21", salesInMillions: 25),
  (title: "Jagged Little Pill Year: 1995", salesInMillions: 24),
]

let disposeBag = DisposeBag()

// 过滤专辑销量大于等于 30 的专辑
Observable.from(bestSellingAlbums)
  .filter { album in
    album.salesInMillions >= 30
  }
  .subscribe(onNext: {
    print($0)
  })
  .disposed(by: disposeBag)
  
// Output: 
// (title: "Thriller", salesInMillions: 93)
// (title: "Eagles: Their Greatest Hits 1971-1975", salesInMillions: 41)
// (title: "Hotel California", salesInMillions: 32)

2. skip() & skipWhile()

顾名思义,这两个运算符的目的是在某个时刻跳过数据。

使用 skip 运算符,你可以将数字作为参数传递给它。这个数字告诉我们要忽略多少元素。随后的所有元素都被允许传递给订阅者。因此,skip(2) 将忽略前两个元素并通过后续的所有其他元素。

使用 skipWhile 运算符,你可以传递一个谓词,只要计算结果为 true,就会忽略传入的元素。当它的值为 false 时,后面的所有元素都将被允许通过。

让我们用代码来看一下:

swift 复制代码
import RxSwift

let bestSellingAlbums = [
  (title: "Thriller", salesInMillions: 93),
  (title: "Eagles: Their Greatest Hits 1971-1975", salesInMillions: 41),
  (title: "Hotel California", salesInMillions: 32),
  (title: "Come on Over", salesInMillions: 29),
  (title: "Led Zeppelin IV", salesInMillions: 29),
  (title: "The Bodyguard Soundtrack", salesInMillions: 28),
  (title: "Rumours", salesInMillions: 27),
  (title: "Back in Black", salesInMillions: 26),
  (title: "21", salesInMillions: 25),
  (title: "Jagged Little Pill Year: 1995", salesInMillions: 24),
]

let disposeBag = DisposeBag()

// 跳过专辑销量大于等于 30 的专辑
Observable.from(bestSellingAlbums)
  .skipWhile { album in
    album.salesInMillions > 30
  }
  .subscribe(onNext: {
    print($0)
  })
  .disposed(by: disposeBag)
  
// Output: 
// (title: "Come on Over", salesInMillions: 29)
// (title: "Led Zeppelin IV", salesInMillions: 29)
// (title: "The Bodyguard Soundtrack", salesInMillions: 28)
// (title: "Rumours", salesInMillions: 27)
// (title: "Back in Black", salesInMillions: 26)
// (title: "21", salesInMillions: 25)
// (title: "Jagged Little Pill Year: 1995", salesInMillions: 24)

3. take() & takeWhile()

接下来,我们有各种获取运算符。这些与跳过运算符相反。跳过运算符将根据条件排除某些数据,但获取运算符将按照你指定的方式包含数据。

take 运算符与 skip 运算符相反。它按照你的预期工作。使用 take 运算符,你可以指定允许通过的一定数量的元素。该数字之后的所有元素都将被忽略。

你猜对了,takeWhile 运算符与 skipWhile 运算符相反。使用 takeWhile 运算符,您可以传递一个谓词,只要计算结果为 true,就允许传入元素。当它的计算结果为 false 时,后面的所有元素都将被忽略。

4. elementAt()

这是一个你不能忽视的漂亮的小运算符。 elementAt 运算符将过滤掉除您在某个索引处指定的元素之外的所有后续事件。

在代码中,它将如下所示:

swift 复制代码
import RxSwift

let bestSellingAlbums = [
  (title: "Thriller", salesInMillions: 93),
  (title: "Eagles: Their Greatest Hits 1971-1975", salesInMillions: 41),
  (title: "Hotel California", salesInMillions: 32),
  (title: "Come on Over", salesInMillions: 29),
  (title: "Led Zeppelin IV", salesInMillions: 29),
  (title: "The Bodyguard Soundtrack", salesInMillions: 28),
  (title: "Rumours", salesInMillions: 27),
  (title: "Back in Black", salesInMillions: 26),
  (title: "21", salesInMillions: 25),
  (title: "Jagged Little Pill Year: 1995", salesInMillions: 24),
]

let disposeBag = DisposeBag()

Observable.from(bestSellingAlbums)
  .elementAt(5) // 只获取第6个元素
  .subscribe(onNext: {
    print($0)
  })
  .disposed(by: disposeBag)
  
// Output: 
// (title: "The Bodyguard Soundtrack", salesInMillions: 28),

5. ignoreElements()

最后但同样重要的是,我们有 ignoreElements 操作符。

正如你从这个弹珠图中看到的,ignoreElements() 将简单地忽略所有 next 事件元素。这样,你可以忽略 next 事件,仅订阅停止事件并相应地执行操作。

总结

我们研究了 RxSwift 提供的最常见的过滤运算符。你可以在[此处](谢谢阅读。留下封面让我知道您希望我介绍的其他 RxSwift 相关主题。)找到可用操作符的完整列表。

谢谢阅读。留言让我知道你希望我介绍的其他 RxSwift 相关主题。

相关推荐
用户092 小时前
如何避免写垃圾代码:iOS开发篇
ios·swiftui·swift
HarderCoder2 小时前
Swift 语法速通:iOS 开发必会的 8 大核心概念(图解+类比)
swift
HarderCoder3 小时前
Swift 6 并发编程:深入理解 `@unchecked Sendable` 的合法使用与陷阱
swift
HarderCoder3 小时前
Swift 6.0 协议扩展:解锁协议新特性,写出更优雅、更高效的代码
swift
HarderCoder2 天前
Swift 6 并发时代,如何优雅地“抢救”你的单例?
swift
zhangmeng2 天前
FlutterBoost在iOS26真机运行崩溃问题
flutter·app·swift
HarderCoder2 天前
SwiftUI 踩坑记:onAppear / task 不回调?90% 撞上了“空壳视图”!
swift
HarderCoder2 天前
@isolated(any) 深度解析:Swift 并发中的“隔离追踪器”
swift
大熊猫侯佩2 天前
桃花岛 Xcode 构建秘籍:Swift 中的 “Feature Flags” 心法
app·xcode·swift
用户092 天前
SwiftUI Charts 函数绘图完全指南
ios·swiftui·swift