在Swift Combine中保存过滤逻辑。第2部分

面向数据的组合





本文的翻译是专为高级课程“ 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演示中,您可能会发现运算符列表非常空白。在接下来的几周中,我们将用各种类型的运算符填充它:转换运算符mapscan
您可以在Combine-Playground文件夹中的Combine-magic-swifui存储库中找到源代码

我们期待着您的意见,并邀请您参加本课程的开放日

All Articles