Datenorientiertes Kombinieren
Die Übersetzung des Artikels wurde speziell für Studenten des Fortgeschrittenenkurses "iOS Developer" vorbereitet .
In der vorherigen Folge haben wir erfolgreich einen Wertestrom modelliert, bei dem jedem Wert ein einfacher Operator ( delay
) zugeordnet wurde .In diesem Teil werden wir uns einige weitere Operatoren ansehen Codeable
, sie erstellen und sie schließlich zur Laufzeit in Combine Publisher konvertieren.
Operatortypen
Bevor wir beginnen, sie zu modellieren, müssen wir verstehen, welche Arten von Operatoren existieren.Die ReactiveX-Site unterteilt sie in ungefähr 10 Kategorien: Erstellung, Transformation, Filterung, Kombination, Fehlerbehandlung, Hilfs-, bedingte, mathematische / aggregierte, Gegendruck-, Konnektiv-Beobachtbar- und Beobachtbar (To) -Konvertierungsoperatoren. Wenn Sie interessiert sind, hat ReactiveX eine gute Erklärung für jeden Typ und Operator.Hinweis: Wenn Sie mit RxSwift nicht vertraut sind, entspricht Observable in RxSwift Publisher in Combine.
Im vorherigen Teil haben wir den Operator erwähnt delay
, der sich auf den utility
Typ auxiliary ( ) bezieht . Heute konzentrieren wir uns auf die Beibehaltung von zwei filtering ( filtering
) -Operatoren.
Filteroperatoren
Diese Art von Bediener verhindert, dass sich alle oder einige (oder keine) der Strömungselemente basierend auf dieser Bedingung weiter stromaufwärts bewegen.dropFirst
dropFirst
stoppt die Übertragung der ersten n
Elemente. Wir können es Operator
aufgrund seiner Einfachheit einfach zu unserer Aufzählung hinzufügen .enum Operator {
case delay(seconds: Double)
case dropFirst(count: Int)
}
Wir können diesen Auflistungsfall auch problemlos in Publisher konvertieren.extension Operator {func applyPublisher<T>(_ publisher: AnyPublisher<T, Never>) -> AnyPublisher<T, Never> {
switch self {
case .dropFirst(let count):
return publisher.dropFirst(count).eraseToAnyPublisher()
}}}
Jetzt kann der Operator dropFirst
gespeichert und in der Operatorliste angezeigt werden.
Das Speichern dropFirst
ähnelt einem Operator delay
. Vielleicht unterscheidet sich die Filterung nicht so sehr von den Hilfsoperatoren. Versuchen wir es mit einer anderen Aussage, bevor wir eine solche Schlussfolgerung ziehen.Filter
Im Gegensatz dazu verwendet dropFirst
der Operator, der sehr einfache Filterkriterien hat, den filter
Abschluss anstelle eines primitiven Typs. Dies ist ein komplizierterer Fall. Wie speichern und verbreiten wir eine Schließung?filter(_:)
Veröffentlicht alle Elemente, die dem angegebenen Abschluss entsprechen, erneut.
developer.apple.com
Schauen wir uns die Methode filter
genauer an .func filter(_ isIncluded: @escaping (Self.Output) -> Bool) -> Publishers.Filter<Self>
Sein Abschluss isIncluded
nimmt einen universellen Typ an und gibt einen booleschen Wert zurück.Gibt es irgendetwas in Foundation, das logische Bedingungen darstellt und einen logischen Wert zurückgibt? Erinnert mich an etwas?Filtern Sie mit NSPredicate
Die Antwort lautet NSPredicate
. Wenn wir die Filterbedingungen als Ausdrücke im Zeichenfolgenformat speichern können, können wir einfach den Wert des Streams übergeben und ihn NSPredicate
zur Auswertung der Ergebnisse verwenden.Fahren wir fort und ergänzen filter
die Liste.enum Operator {
case delay(seconds: Double)
case dropFirst(count: Int)
case filter(expression: String)
}
Alles was wir tun müssen, ist Ausdrücke wie %d !=3
oder zu filtern %@ != “D”
; Daher ist Ausdruck ein geeigneter Typ. Ebenso sollten wir in der Lage sein, die Liste filter
nach Publisher zu verschieben.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()
}}}
Wie geplant senden wir den Ausdruck NSPredicate
zusammen mit dem vom Publisher gesendeten Wert an.Beachten Sie, dass NSPredicate
ein Array von Argumenten akzeptiert wird. Daher sollte es mit einigen Änderungen funktionieren, selbst wenn die Werte das Format von Tupeln annehmen, was in reaktiven Szenarien sehr häufig ist. Wir werden in Zukunft darauf zurückkommen, wenn wir über kombinierte Betreiber sprechen.
Wie Sie sehen können, wird Filter Stream zu diesem gespeicherten Array von Anweisungen hinzugefügt und in Publisher konvertiert, um die Nummer 3 aus den höheren Werten zu filtern.
In der nächsten Folge: Transformationsoperatoren speichern, Karte und Scan
In der GIF-Demo stellen Sie möglicherweise fest, dass die Liste der Operatoren ziemlich leer ist. In den nächsten Wochen werden wir es mit verschiedenen Arten von Operatoren füllen: Transformationsoperatoren map
und scan
.Sie finden den Quellcode in diesem Repository für Mähdrescher-Magie-Swifui im Ordner Mähdrescher-Spielplatz.Wir freuen uns auf Ihre Kommentare und laden Sie zum Tag der offenen Tür ein .