本文主要是介绍Swift Combine — Operators(常用Filtering类操作符介绍),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
目录
- filter(_: )
- tryFilter(_: )
- compactMap(_: )
- tryCompactMap(_: )
- removeDuplicates()
- first(where:)
- last(where:)
Combine
中对
Publisher
的值进行操作的方法称为
Operator
(操作符)。
Combine
中的
Operator
通常会生成一个
Publisher
,该
Publisher
处理传入事件,对其进行转换,然后将更改后的事件发送给
Subscriber
。
本篇文章主要介绍一下过滤这一类的操作符。
filter(_: )
filter
操作符主要用户过滤数据,比如下面的数据中,将大于5的数输出。
func filterSample() {let intArray = [1, 2, 3, 4, 5, 6, 7, 8, 9]_ = intArray.publisher.filter {$0 > 5}.sink { value inprint("value is : \(value)")}
}
输出为:
value is : 6
value is : 7
value is : 8
value is : 9
tryFilter(_: )
使用tryFilter(_:)
来过滤在抛出错误的闭包中求值的元素。如果闭包抛出错误,则Publisher
将因该错误而失败终止。
func tryFilterSample() {struct ZeroError: Error {}let intArray = [1, 2, 3, 4, 5, 6, 0, 8, 9]_ = intArray.publisher.tryFilter {if $0 == 0 {throw ZeroError()} else {return $0 > 5}}.sink(receiveCompletion: { completion inprint("Received completion: \(completion)")}, receiveValue: { value inprint("Received value: \(value)")})
}
当tryFilter
闭包接收到0时,抛出错误,整个Publisher
链结束。上面输出结果为:
Received value: 6
Received completion: failure((extension in CombineLearning_PreviewReplacement_OperatorDemo_1):CombineLearning.OperatorViewModel.(unknown context at $1055a3cdc).(unknown context at $1055a3ce8).ZeroError())
compactMap(_: )
Combine
的compactMap(_:)
操作符的功能与Swift标准
库中的compactMap(_:)
类似。
Combine
中的compactMap(_:)
操作符移除Publisher流中的nil元素,并将非nil元素重新发布给下游订阅者。
func compactMapSample() {let numbers = (0...5)let romanNumeralDict: [Int : String] = [1: "one", 2: "two", 3: "three", 5: "five"]_ = numbers.publisher.compactMap { romanNumeralDict[$0] }.sink { print("\($0)", terminator: " ") }
}
当通过key为4的值的时候为nil了,所以这里将nil去除了。
输出结果为:
one two three five
tryCompactMap(_: )
tryCompactMap(_: )
相比compactMap(_:)
除了都能去除nil外,前者还能在闭包内抛出错误。
如果闭包抛出错误,则Publisher
流将因该错误而失败终止。
func tryCompactMapSample() {struct ParseError: Error {}func romanNumeral(from: Int) throws -> String? {let romanNumeralDict: [Int : String] =[1: "one", 2: "two", 3: "three", 4: "four", 5: "five"]guard from != 0 else { throw ParseError() }return romanNumeralDict[from]}let numbers = [6, 5, 4, 3, 2, 1, 0]_ = numbers.publisher.tryCompactMap { try romanNumeral(from: $0) }.sink(receiveCompletion: { print ("\($0)") },receiveValue: { print ("\($0)", terminator: " ") })}
在上面代码中,当取key为6的元素时为nil,这个nil没有继续往下发送。当取key为0的元素时,抛出了错误,随后Publisher
流结束。
输出结果为:
five four three two one failure((extension in CombineLearning_PreviewReplacement_OperatorDemo_1):CombineLearning.OperatorViewModel.(unknown context at $104a0bbec).(unknown context at $104a0bbf8).ParseError())
removeDuplicates()
有些时候下游的订阅者不希望收到重复的数据,那么用removeDuplicates
方法可以去除重复数据。
func removeDuplicatesSample() {let intArray = [1, 1, 3, 5, 5, 6, 7, 8, 9]_ = intArray.publisher.removeDuplicates().sink { value inprint("value is : \(value)")}
}
上面代码中将数组中重复的数据去除,然后输出。
输出为:
value is : 1
value is : 3
value is : 5
value is : 6
value is : 7
value is : 8
value is : 9
另外需要注意removeDuplicates
操作符不会将Publisher
作为一个集合去排重,而是随着时间根据上下接收到的数据排重,如果相同的数据不挨着,那么不会认为是重复的。
func removeDuplicatesSample() {let intArray = [1, 1, 3, 5, 5, 6, 7, 1, 5]_ = intArray.publisher.removeDuplicates().sink { value inprint("value is : \(value)")}
}
上面数组中在末尾又添加了1和5,看看输出结果:
value is : 1
value is : 3
value is : 5
value is : 6
value is : 7
value is : 1
value is : 5
first(where:)
first(where:)
操作符和filter
操作符很相似,filter
是找出所有满足条件的数据,而first(where:)
操作符是找出第一个满足条件的数据。
func firstWhereSample() {let intArray = [1, 2, 3, 3, 5, 6, 7, 8, 9]_ = intArray.publisher.first {$0 > 5}.sink(receiveCompletion: { completion inprint("Received completion")}, receiveValue: { value inprint("Received value: \(value)")})
}
比如上面代码找出第一个大于5的数据,结果如下:
Received value: 6
Received completion
last(where:)
last(where:)
和first(where:)
操作符正好相反, last(where:)
操作符查找符合条件的最后一个数据。
func lastWhereSample() {let intArray = [1, 5, 3, 7, 2, 6, 4, 8, 9]_ = intArray.publisher.last {$0 < 6}.sink(receiveCompletion: { completion inprint("Received completion")}, receiveValue: { value inprint("Received value: \(value)")})
}
上面代码找出小于6的最后一个元素,输出结果为:
Received value: 4
Received completion
如果是找出大于6的最后一个元素,输出结果为:
Received value: 9
Received completion
最后,希望能够帮助到有需要的朋友,如果觉得有帮助,还望点个赞,添加个关注,笔者也会不断地努力,写出更多更好用的文章。
这篇关于Swift Combine — Operators(常用Filtering类操作符介绍)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!