[英]Combine previous value using Combine
我對ReactiveSwift/ReactiveCocoa
並不完全熟悉,但根據您的描述,您可以使用.scan
,這似乎是一個比combinePrevious
更通用的函數。
它需要一個初始結果——你可以把它變成一個元組——以及一個帶有存儲值和當前值的閉包,並返回一個新的存儲值——在你的情況下,一個帶有(previous, current)
的元組:
let producer = [1,2,3].publisher
.scan((0,0)) { ($0.1, $1) }
producer.sink {
print($0)
}
這些是我想出的自定義運算符(稱為withPrevious
)。 有兩種重載,一種是初始值nil
,另一種是提供初始值,這樣您就不必處理可選項。
extension Publisher {
/// Includes the current element as well as the previous element from the upstream publisher in a tuple where the previous element is optional.
/// The first time the upstream publisher emits an element, the previous element will be `nil`.
///
/// let range = (1...5)
/// cancellable = range.publisher
/// .withPrevious()
/// .sink { print ("(\($0.previous), \($0.current))", terminator: " ") }
/// // Prints: "(nil, 1) (Optional(1), 2) (Optional(2), 3) (Optional(3), 4) (Optional(4), 5) ".
///
/// - Returns: A publisher of a tuple of the previous and current elements from the upstream publisher.
func withPrevious() -> AnyPublisher<(previous: Output?, current: Output), Failure> {
scan(Optional<(Output?, Output)>.none) { ($0?.1, $1) }
.compactMap { $0 }
.eraseToAnyPublisher()
}
/// Includes the current element as well as the previous element from the upstream publisher in a tuple where the previous element is not optional.
/// The first time the upstream publisher emits an element, the previous element will be the `initialPreviousValue`.
///
/// let range = (1...5)
/// cancellable = range.publisher
/// .withPrevious(0)
/// .sink { print ("(\($0.previous), \($0.current))", terminator: " ") }
/// // Prints: "(0, 1) (1, 2) (2, 3) (3, 4) (4, 5) ".
///
/// - Parameter initialPreviousValue: The initial value to use as the "previous" value when the upstream publisher emits for the first time.
/// - Returns: A publisher of a tuple of the previous and current elements from the upstream publisher.
func withPrevious(_ initialPreviousValue: Output) -> AnyPublisher<(previous: Output, current: Output), Failure> {
scan((initialPreviousValue, initialPreviousValue)) { ($0.1, $1) }.eraseToAnyPublisher()
}
}
Cocoacasts 有一個很好的例子:
https://cocoacasts.com/combine-essentials-combining-publishers-with-combine-zip-operator
zip 運算符可用於創建發布者,該發布者發出前一個元素和發布者發出的當前元素。 我們將同一個發布者傳遞給 Publishers.Zip 結構的初始化程序兩次,但將 dropFirst 運算符應用於第二個發布者。 這僅僅意味着第二個發布者不會發出原始發布者的第一個元素。
import Combine
let numbers = [1, 2, 3, 4, 5].publisher
Publishers.Zip(numbers, numbers.dropFirst(1))
用法:
import Combine
let numbers = [1, 2, 3, 4, 5].publisher
Publishers.Zip(numbers, numbers.dropFirst(1))
.sink(receiveValue: { values in
print(values)
})
// (1, 2)
// (2, 3)
// (3, 4)
// (4, 5)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.