面向数据的组合
本文的翻译是专为高级课程“ iOS Developer”的学生准备的。
在上一集中,我们成功地对值流进行了建模,每个值都附加了一个简单的运算符(delay
)。在这一部分中,我们将研究更多的运算符,进行制作,Codeable
最后在运行时将其转换为Combine Publisher。
操作员类型
在开始对它们进行建模之前,我们需要了解存在哪些类型的运算符。ReactiveX网站将它们分为10类:创建,转换,过滤,合并,错误处理,辅助,条件,数学/聚合,背压,可连接可观察和可观察(To)转换运算符。如果您有兴趣,ReactiveX对每种类型和运算符都有很好的解释。注意:如果您不熟悉RxSwift,则RxSwift中的Observable等同于Combine中的Publisher。
在上一部分中,我们提到了operator delay
,它表示辅助(utility
)类型。今天,我们将重点关注保留两个过滤(filtering
)运算符。
过滤运算符
基于这种情况,这种类型的操作器可防止所有或某些(或没有)流量元件进一步向上游移动。dropFirst
dropFirst
停止传输第一个n
元素。Operator
鉴于其简单性,我们可以简单地将其添加到我们的枚举中。enum Operator {
case delay(seconds: Double)
case dropFirst(count: Int)
}
我们还可以轻松地将此列表案例转换为Publisher。extension Operator {func applyPublisher<T>(_ publisher: AnyPublisher<T, Never>) -> AnyPublisher<T, Never> {
switch self {
case .dropFirst(let count):
return publisher.dropFirst(count).eraseToAnyPublisher()
}}}
现在dropFirst
可以保存操作员并将其显示在操作员列表中。
保存dropFirst
类似于操作员delay
。也许过滤与辅助运算符没有太大区别。好吧,在得出这样的结论之前,让我们尝试另一种说法。过滤
相反dropFirst
,具有非常简单的过滤条件,操作员filter
使用闭包而不是原始类型。这是一个更复杂的情况。我们如何保存和传播封闭?filter(_:)
重新发布与给定闭包匹配的所有元素。
developer.apple.com
让我们filter
仔细看看该方法。func filter(_ isIncluded: @escaping (Self.Output) -> Bool) -> Publishers.Filter<Self>
它的闭包isIncluded
采用通用类型,并返回布尔值。Foundation中是否有任何东西可以表示逻辑条件并返回逻辑值?让我想起了什么?用NSPredicate过滤
答案是NSPredicate
。如果我们可以将过滤条件保存为字符串格式的表达式,则可以简单地传递流的值并将其NSPredicate
用于评估结果。让我们继续并添加filter
到清单中。enum Operator {
case delay(seconds: Double)
case dropFirst(count: Int)
case filter(expression: String)
}
我们需要做的只是过滤器表达式,例如%d !=3
或%@ != “D”
; 因此,表达式是一种合适的类型。同样,我们应该能够将列表移动filter
到Publisher。extension Operator {
func applyPublisher<T>(_ publisher: AnyPublisher<T, Never>) -> AnyPublisher<T, Never> {
switch self {
case .filter(let expression):
return publisher.filter { value in
NSPredicate(format: expression,
argumentArray: [value])
.evaluate(with: nil) }.eraseToAnyPublisher()
}}}
按照计划,我们将表达式NSPredicate
与发布服务器发送的值一起发送到。请注意,它NSPredicate
接受一个参数数组。因此,即使值假定为元组的格式,它也应该进行一些修改,这在反应性场景中很常见。将来,当我们谈论组合运算符时,我们将回到这一点。
如您所见,Filter Stream被添加到此保存的语句数组中,并转换为Publisher以从较高的值中过滤数字3。
在下一集中:保存转换运算符,地图和扫描
在GIF演示中,您可能会发现运算符列表非常空白。在接下来的几周中,我们将用各种类型的运算符填充它:转换运算符map
和scan
。您可以在Combine-Playground文件夹中的Combine-magic-swifui存储库中找到源代码。我们期待着您的意见,并邀请您参加本课程的开放日。