你应该知道的5个Swift组合变换操作符
本文转载自公众号“读芯术”(ID:AI_Discovery)。应该
想随时随地轻松变更数据格式?知道t组作符本文将教你5种解法!我将在Xcode Playground中创建示例函数,运行它们并观察结果。合变换操
1. map
.map 操作符允许我们转换闭包中来自发布者的应该所有元素。
var subscriptions =Set<AnyCancellable>() funcmapExample() { let subject =PassthroughSubject<Int,知道t组作符 Never>() subject .map { (integer) in returnString(integer) } .sink(receiveValue: { print("Value: \($0), Type: \(type(of: $0))") }) .store(in: &subscriptions) subject.send(12) subject.send(31) subject.send(55) subject.send(4) subject.send(18) }下面是这段代码的作用:
创建一个接受Int 值的PassthroughSubject。 使用.map 操作符将每个接收到的合变换操Int 值转换为String。 然后,应该订阅发布者并打印转换后的知道t组作符元素的值和类型。向受试者发送随机数以观察以下结果:

还有一种巧妙的合变换操方法来使用对象的键路径获取对象的属性:
funcmapKeyPathExample() { structCarBrand { let title:String let country:String } let carBrandsSubject =PassthroughSubject<CarBrand, Never>() carBrandsSubject .map(\.country) .sink(receiveValue: { country in print("Country:\(country)") }) .store(in: &subscriptions) carBrandsSubject.send( CarBrand(title: "MercedesBenz", country: "Germany") ) carBrandsSubject.send( CarBrand(title: "Ford", country: "USA") ) carBrandsSubject.send( CarBrand(title: "Honda", country: "Japan") ) }使用.map(\.country),可以访问CarBrand的应该国家属性。然后只需打印每个国家:

2. replaceNil
顾名思义,知道t组作符.replaceNil 操作符将每个接收到的合变换操nil元素转换为指定的元素:
funcreplaceNilExample() { let values: [Int?] = [123, nil, nil, 12, 10] let valuesvaluesPublisher =values.publisher valuesPublisher .replaceNil(with: 0) .map { $0! } .collect() .sink(receiveValue: { print($0) }) .store(in: &subscriptions) }请注意,站群服务器还可以将多个操作符组合在一起以达到必要的应该结果。首先将每个nil 值替换为0,知道t组作符然后强制解开值,合变换操最后将所有值收集在一个数组中:

需要注意的是在.map 操作符中使用强制展开的方法。如果你不喜欢强行解包该怎么办?我们还有一个.map协变量:.compactMap,它能自动转发仅非零的那些元素:
funcreplaceNilExample() { let values: [Int?] = [123, nil, nil, 12, 10] let valuesvaluesPublisher = values.publisher valuesPublisher .replaceNil(with: 0) .compactMap { $0 } .collect() .sink(receiveValue: { print($0) }) .store(in: &subscriptions) }3. collect
使用.collect操作符可以很容易地收集所有接收到的元素,并发出一个包含所有元素的数组:
funccollectExample() { let integers = [1, 4, 5, 12, 24, 44] let integerPublisher =integers.publisher integerPublisher .collect() .sink(receiveValue: { print($0) }) .store(in: &subscriptions) }于是我们得到了想要的结果:

注意,发布者必须发出.completed事件才能实现这个操作,因为.collect会一直等待,直到所有元素都发出并且发布者完成操作为止。例如,如果使用PassthroughSubject,需要在发送所有元素后发送.finished事件:
funccollectExample() { let integerPublisher =PassthroughSubject<Int, Never>() integerPublisher .collect() .sink(receiveValue: { print($0) }) .store(in: &subscriptions) integerPublisher.send(1) integerPublisher.send(4) integerPublisher.send(5) integerPublisher.send(12) integerPublisher.send(24) integerPublisher.send(44) integerPublisher.send(completion: .finished) }4. flatMap
.flatMap操作符允许我们将给定的发布者转换为另一个发布者。来看看它是云服务器如何将观察结果从Network更改为isAvailable主题:
funccollectExample() { let integerPublisher =PassthroughSubject<Int, Never>() integerPublisher .collect() .sink(receiveValue: { print($0) }) .store(in: &subscriptions) integerPublisher.send(1) integerPublisher.send(4) integerPublisher.send(5) integerPublisher.send(12) integerPublisher.send(24) integerPublisher.send(44) integerPublisher.send(completion: .finished) }当更改它的值时,我们要打印出isAvailable值。首先,它打印初始值(正在使用CurrentValueSubject),一旦为其分配了新值,就会发生以下情况:

5. scan
.scan操作符能够在闭包中公开当前发出的值以及最新的值。可以使用它来累积值并打印总结果:
funcflatMapExample() { structNetwork { let title:String let isAvailable =CurrentValueSubject<Bool, Never>(false) } let wifi =Network(title: "Wi-Fi") let networkSubject = CurrentValueSubject<Network, Never>(wifi) networkSubject .flatMap ({ return$0.isAvailable }) .sink(receiveValue: { print("Is networkenabled: \($0)") }) .store(in: &subscriptions) wifi.isAvailable.value=true wifi.isAvailable.value=false }在这里,执行的是以下操作:
创建收益数组(下划线是将数字中的千单位分开的好方法)。 创建这些收益的发布者。 使用.scan操作符,将当前发出的值($0)添加到从零开始的最新值($1)。最后,计算出总收益:
【责任编辑:赵宁宁 TEL:(010)68476606】
香港云服务器