你应该知道的5个Swift组合变换操作符

开发 前端
想随时随地轻松变更数据格式?本文将教你5种解法!我将在Xcode Playground中创建示例函数,运行它们并观察结果。

本文转载自公众号“读芯术”(ID:AI_Discovery)。

想随时随地轻松变更数据格式?本文将教你5种解法!我将在Xcode Playground中创建示例函数,运行它们并观察结果。

[[334295]]

1. map

.map 操作符允许我们转换闭包中来自发布者的所有元素。

  1. var subscriptions =Set<AnyCancellable>() 
  2.                                             funcmapExample() { 
  3.                           let subject =PassthroughSubject<Int, Never>() 
  4.                           subject 
  5.                               .map { (integer) in 
  6.                                   returnString(integer) 
  7.                           } 
  8.                           .sink(receiveValue: { 
  9.                               print("Value: \($0), Type: \(type(of: $0))") 
  10.                           }) 
  11.                           .store(in: &subscriptions) 
  12.                           subject.send(12) 
  13.                           subject.send(31) 
  14.                           subject.send(55) 
  15.                           subject.send(4) 
  16.                           subject.send(18) 
  17.                       } 

下面是这段代码的作用:

  • 创建一个接受Int 值的PassthroughSubject。
  • 使用.map 操作符将每个接收到的Int 值转换为String。
  • 然后,订阅发布者并打印转换后的元素的值和类型。

向受试者发送随机数以观察以下结果:

你应该知道的5个Swift组合变换操作符

还有一种巧妙的方法来使用对象的键路径获取对象的属性:

  1. funcmapKeyPathExample() { 
  2.                         structCarBrand { 
  3.                             let title:String 
  4.                             let country:String 
  5.                         } 
  6.                                let carBrandsSubject =PassthroughSubject<CarBrand, Never>() 
  7.                           carBrandsSubject 
  8.                             .map(\.country) 
  9.                             .sink(receiveValue: { country in 
  10.                                 print("Country:\(country)") 
  11.                             }) 
  12.                             .store(in: &subscriptions) 
  13.                                carBrandsSubject.send( 
  14.                             CarBrand(title: "MercedesBenz", country: "Germany") 
  15.                         ) 
  16.                                carBrandsSubject.send( 
  17.                             CarBrand(title: "Ford", country: "USA") 
  18.                         ) 
  19.                                carBrandsSubject.send( 
  20.                             CarBrand(title: "Honda", country: "Japan") 
  21.                         ) 
  22.                     } 

使用.map(\.country),可以访问CarBrand的国家属性。然后只需打印每个国家:

你应该知道的5个Swift组合变换操作符

2. replaceNil

顾名思义,.replaceNil 操作符将每个接收到的nil元素转换为指定的元素:

  1. funcreplaceNilExample() { 
  2.                         let values: [Int?] = [123, nil, nil, 12, 10] 
  3.                         let valuesvaluesPublisher =values.publisher 
  4.                                valuesPublisher 
  5.                             .replaceNil(with: 0) 
  6.                             .map { $0! } 
  7.                             .collect() 
  8.                             .sink(receiveValue: { print($0) }) 
  9.                             .store(in: &subscriptions) 
  10.                     } 

请注意,还可以将多个操作符组合在一起以达到必要的结果。首先将每个nil 值替换为0,然后强制解开值,最后将所有值收集在一个数组中:

你应该知道的5个Swift组合变换操作符

需要注意的是在.map 操作符中使用强制展开的方法。如果你不喜欢强行解包该怎么办?我们还有一个.map协变量:.compactMap,它能自动转发仅非零的那些元素:

  1. funcreplaceNilExample() { 
  2.                         let values: [Int?] = [123, nil, nil, 12, 10] 
  3.                         let valuesvaluesPublisher = values.publisher 
  4.                                valuesPublisher 
  5.                             .replaceNil(with: 0) 
  6.                             .compactMap { $0 } 
  7.                             .collect() 
  8.                             .sink(receiveValue: { print($0) }) 
  9.                             .store(in: &subscriptions) 
  10.     } 

3. collect

使用.collect操作符可以很容易地收集所有接收到的元素,并发出一个包含所有元素的数组:

  1. funccollectExample() { 
  2.                      let integers = [1, 4, 5, 12, 24, 44] 
  3.                            let integerPublisher =integers.publisher 
  4.                            integerPublisher 
  5.                          .collect() 
  6.                          .sink(receiveValue: { print($0) }) 
  7.                          .store(in: &subscriptions) 
  8.                  } 

于是我们得到了想要的结果:

你应该知道的5个Swift组合变换操作符

注意,发布者必须发出.completed事件才能实现这个操作,因为.collect会一直等待,直到所有元素都发出并且发布者完成操作为止。例如,如果使用PassthroughSubject,需要在发送所有元素后发送.finished事件:

  1. funccollectExample() { 
  2.                      let integerPublisher =PassthroughSubject<Int, Never>() 
  3.                            integerPublisher 
  4.                          .collect() 
  5.                          .sink(receiveValue: { print($0) }) 
  6.                          .store(in: &subscriptions) 
  7.                            integerPublisher.send(1) 
  8.                      integerPublisher.send(4) 
  9.                      integerPublisher.send(5) 
  10.                      integerPublisher.send(12) 
  11.                      integerPublisher.send(24) 
  12.                      integerPublisher.send(44) 
  13.                            integerPublisher.send(completion: .finished) 
  14.                  } 

4. flatMap

.flatMap操作符允许我们将给定的发布者转换为另一个发布者。来看看它是如何将观察结果从Network更改为isAvailable主题:

  1. funccollectExample() { 
  2.                      let integerPublisher =PassthroughSubject<Int, Never>() 
  3.                            integerPublisher 
  4.                          .collect() 
  5.                          .sink(receiveValue: { print($0) }) 
  6.                          .store(in: &subscriptions) 
  7.                            integerPublisher.send(1) 
  8.                      integerPublisher.send(4) 
  9.                      integerPublisher.send(5) 
  10.                      integerPublisher.send(12) 
  11.                      integerPublisher.send(24) 
  12.                      integerPublisher.send(44) 
  13.                            integerPublisher.send(completion: .finished) 
  14.                  } 

当更改它的值时,我们要打印出isAvailable值。首先,它打印初始值(正在使用CurrentValueSubject),一旦为其分配了新值,就会发生以下情况:

你应该知道的5个Swift组合变换操作符

5. scan

.scan操作符能够在闭包中公开当前发出的值以及最新的值。可以使用它来累积值并打印总结果:

  1. funcflatMapExample() { 
  2.                      structNetwork { 
  3.                          let title:String 
  4.                          let isAvailable =CurrentValueSubject<Bool, Never>(false) 
  5.                      } 
  6.                            let wifi =Network(title: "Wi-Fi") 
  7.                            let networkSubject = CurrentValueSubject<Network, Never>(wifi) 
  8.                            networkSubject 
  9.                          .flatMap ({ 
  10.                              return$0.isAvailable 
  11.                          }) 
  12.                          .sink(receiveValue: { 
  13.                              print("Is networkenabled: \($0)") 
  14.                          }) 
  15.                          .store(in: &subscriptions) 
  16.                            wifi.isAvailable.value=true 
  17.                            wifi.isAvailable.value=false 
  18.                  } 

在这里,执行的是以下操作:

  • 创建收益数组(下划线是将数字中的千单位分开的好方法)。
  • 创建这些收益的发布者。
  • 使用.scan操作符,将当前发出的值($0)添加到从零开始的最新值($1)。

最后,计算出总收益:

你应该知道的5个Swift组合变换操作符

【责任编辑:赵宁宁 TEL:(010)68476606】

 

责任编辑:赵宁宁 来源: 今日头条
相关推荐

2017-06-06 11:59:26

Docker工具容器

2022-09-07 09:01:14

JS操作符运算符

2024-03-26 10:10:45

JavaScript操作符操作表达式

2020-04-03 19:21:59

JavaScript编程语言开发

2021-07-01 11:07:49

Swift 自定义操作符

2016-02-25 10:58:01

Live Linux桌面发行版

2010-07-14 14:55:07

Perl操作符

2009-08-19 17:26:28

C# 操作符

2009-07-21 09:31:00

Scala操作符

2021-10-31 18:59:55

Python操作符用法

2024-11-12 14:56:07

2020-11-18 08:15:39

TypeScript设计模式

2009-11-30 16:48:08

PHP操作符

2009-07-14 18:34:22

Jython操作符重载

2010-07-13 11:11:39

Perl标量

2020-10-18 07:37:24

微前端框架前端

2022-06-29 10:06:27

Webpack优化技巧前端

2017-04-21 21:25:12

操作系统国产

2010-07-14 14:30:31

Perl操作符

2010-07-19 11:00:24

Perl操作符
点赞
收藏

51CTO技术栈公众号