[英]Combine uncollect operator?
我正在尋找與收集運算符相反的運算符:
[1,2,3]
,我想將其轉換為 stream 發出1
然后2
,然后3
。uncollect
運算符不會與collect
完全相反,因為collect
一直等到 stream 完成。 使用uncollect
它應該只在 stream 未完成時處理結果,而不是嘗試完成/取消 stream。 例如,我想這就是uncollect
運算符 function 的方式:
func fibonacci(_ number: Int) -> AnyPublisher<Int, Never> {
Future { ... }.eraseToAnyPublisher()
}
let serverEventStream: AnyPublisher<[Int], Never> = ...
serverEventStream // AnyPublisher<[Int], Never> // Ex. 2 values: `[12, 24]`, `[1, 10, 50]`
.uncollect { $0 } // AnyPublisher<Int, Never> // Ex. 5 values: `12`, `24`, `1`, `10`, `50`
.flatMap { fibonacci($0) } // AnyPublisher<Int, Never> // Ex. 5 values: `144`, `46368`, `1`, `55`, `12586269025`
.sink { print($0) }
我一直在尋找諸如explode
、 splat
或uncollect
之類的名稱,但無濟於事。 最接近的運算符是flatMap
,因為Sequence.flatMap
在非組合世界中是等價的。 然而, Combine 的flatMap
是將 Promise 鏈接在一起的方式。
有沒有辦法取消收集元素,或者 map 將單個發射變成任意數量的發射?
我能夠讓它與我的自定義JustSeveral
Publisher一起使用,但這似乎很笨重:
class Tests: XCTestCase {
func testUncollect() {
func fibonacci(_ number: Int) -> AnyPublisher<Int, Never> {
switch number {
case 1: return Just(1).eraseToAnyPublisher()
case 10: return Just(55).eraseToAnyPublisher()
case 12: return Just(144).eraseToAnyPublisher()
case 24: return Just(46368).eraseToAnyPublisher()
case 50: return Just(12586269025).eraseToAnyPublisher()
default: fatalError("Should actually build this function.")
}
}
let serverEventStream: AnyPublisher<[Int], Never> = JustSeveral([[12, 24], [1, 10, 50]]).eraseToAnyPublisher()
serverEventStream // AnyPublisher<[Int], Never> // Ex. 2 values: `[12, 24]`, `[1, 10, 50]`
.uncollect { $0 } // AnyPublisher<Int, Never> // Ex. 5 values: `12`, `24`, `1`, `10`, `50`
.flatMap { fibonacci($0) } // AnyPublisher<Int, Never> // Ex. 5 values: `144`, `46368`, `1`, `55`, `12586269025`
.sink { print($0) }
}
}
extension Publisher {
func uncollect<T>(_ transform: @escaping (Output) -> [T]) -> AnyPublisher<T, Failure> {
self
.flatMap { output -> AnyPublisher<T, Failure> in
JustSeveral(transform(output))
.setFailureType(to: Failure.self)
.eraseToAnyPublisher()
}
.eraseToAnyPublisher()
}
}
您可以將flatMap
與新的發布者一起使用
[1,2,3,4,5,6].publisher
.collect()
.flatMap { $0.publisher }
.sink { print($0) }
1
2
3
4
5
6
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.