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 相关主题。

相关推荐
大熊猫侯佩10 小时前
由一个 SwiftData “诡异”运行时崩溃而引发的钩深索隐(三)
数据库·swiftui·swift
大熊猫侯佩10 小时前
由一个 SwiftData “诡异”运行时崩溃而引发的钩深索隐(二)
数据库·swiftui·swift
大熊猫侯佩10 小时前
用异步序列优雅的监听 SwiftData 2.0 中历史追踪记录(History Trace)的变化
数据库·swiftui·swift
大熊猫侯佩10 小时前
由一个 SwiftData “诡异”运行时崩溃而引发的钩深索隐(一)
数据库·swiftui·swift
season_zhu1 天前
iOS开发:关于日志框架
ios·架构·swift
大熊猫侯佩1 天前
SwiftUI 中如何花样玩转 SF Symbols 符号动画和过渡特效
swiftui·swift·apple
大熊猫侯佩1 天前
SwiftData 共享数据库在 App 中的改变无法被 Widgets 感知的原因和解决
swiftui·swift·apple
大熊猫侯佩1 天前
使用令牌(Token)进一步优化 SwiftData 2.0 中历史记录追踪(History Trace)的使用
数据库·swift·apple
大熊猫侯佩1 天前
SwiftUI 在 iOS 18 中的 ForEach 点击手势逻辑发生改变的解决
swiftui·swift·apple