filter{ $o.isMultiple(of: 3) }
筛选出3的倍数
let numner = (1...10).publisher
numner.filter{ $0.isMultiple(of: 3) }.sink { n in
print("\(n) is a multiple of 3!")
}.store(in: &subscriptions)
///3 is a multiple of 3!
///6 is a multiple of 3!
///9 is a multiple of 3!
removeDuplicates
removeDuplicates可以用于遵循Equatable协议的值
let words = "hey hey there! want to listen to mister mister ?".components(separatedBy: " ").publisher
words.removeDuplicates().sink(receiveValue: { print($0) }).store(in: &subscriptions)
///hey
///there!
///want
///to
///listen
///to
///mister
///?
上面的结果跳过了相同的单词
Compacting and ignoring
我们可以用 .compactMap来处理emit的nil值
let strings = ["a", "1.24", "3", "def", "45", "0.23"].publisher
strings.compactMap{ Float($0) }.sink(receiveValue: { print($0) }).store(in: &subscriptions)
///1.24 3.0 45.0 0.23
ignoreOutput
let numbers = [1...10_000].publisher
numbers.ignoreOutput().sink(receiveCompletion: { print("Completed with: \($0)") }, receiveValue: { print($0) }).store(in: &subscriptions)
///Completed with: finished
Finding Value
first(where:{})
let number = (1...9).publisher
number.first(where: { $0 % 2 == 0}).sink(receiveCompletion: { print("Completed with: \($0)") }, receiveValue: { print( $0 ) }).store(in: &subscriptions)
/// 2
只会emit第一个满足要求的值
如果我们增加一个print,我们可以观察到更加细致的work
let number = (1...9).publisher
number.print("number").first(where: { $0 % 2 == 0}).sink(receiveCompletion: { print("Completed with: \($0)") }, receiveValue: { print( $0 ) }).store(in: &subscriptions)
/// number: receive subscription: (1...9)
///number: request unlimited
///number: receive value: (1)
///number: receive value: (2)
///number: receive cancel
///2
///Completed with: finished
会发现number接受了订阅,直到emit 的值为2的时候,receive接受到了cancel,然后终止了emit
last(where:{})
last(where: {})和first(where: {})不一样的地方在于first遇到第一个满足条件的element 的时候就会emit cancel去终止emit,但是last必须要有明确的终止信号,如果不明确的终止,last就不知道还不会emit element
let number = PassthroughSubject<Int, Never>()
number.print("number").last(where: { $0 % 2 == 0}).sink(receiveCompletion: { print("Completed with: \($0)") }, receiveValue: { print( $0 ) }).store(in: &subscriptions)
(1...9).forEach{ number.send($0) }
number.send(completion: .finished)
Dropping Value
dropFirst()
考过前3个,直到第四个开始sink
let number = (1...10).publisher
number.dropFirst(8).sink(receiveValue: { print($0) }).store(in: &subscriptions)
/// 9
/// 10
drop(while:)
直到第一个满足条件的element,然后才会sink
let number = (1...10).publisher
number.drop(while: { $0 % 5 != 0 }).sink(receiveValue: { print($0) }).store(in: &subscriptions)
/// 5 6 7 8 9 10
drop(while: {})和filter()的区别还是很大的
drop直到第一个满足条件之后,就不在有过滤筛选的作用了,而filter从头到尾都有筛选的作用,我们可以看一下相同输入下的drop(where: {})和filter()的输出情况
let number = (1...10).publisher
number.drop(while: {
print("drop x")
return $0 % 5 != 0
}).sink(receiveValue: { print($0) }).store(in: &subscriptions)
number.filter({
print("filter x")
return $0 % 5 != 0
}).sink(receiveValue: { print($0) }).store(in: &subscriptions)
/*
*drop(where: {})*
drop x
drop x
drop x
drop x
drop x
5
6
7
8
9
10
*filer()*
filter x
filter x
filter x
filter x
filter x
filter x
filter x
filter x
filter x
filter x
1
2
3
4
6
7
8
9
*/
drop(untilOutputFrom:)
很容易从字面去理解这个函数的功能,直到isReady开始emit的时候,drop开会开始停止skip
let isReady = PassthroughSubject<Void, Never>()
let taps = PassthroughSubject<Int, Never>()
taps.drop(untilOutputFrom: isReady).sink(receiveValue: { print($0) }).store(in: &subscriptions)
(1...5).forEach { n in
taps.send(n)
if n == 3 {
isReady.send()
}
}
///4
///5
Limiting values
prefix()的几个函数与drop()类似,例如prefix(_:),prefix(while:),prefix(untilOutputFrom:),但是他们却截然相反,However, instead of dropping values until some condition is met, the prefix operators take values until that condition is met.
prefix(_:)
drop(2)是skip前2个,从第三个开始sink,
而prefix(2)是sink前两个,从第三个开始skip
let numbers = (1...10).publisher
numbers.prefix(2).sink(receiveCompletion: { print("Completed with: \($0)")}, receiveValue: { print($0) }).store(in: &subscriptions)
/*
1
2
Completed with: finished
*/
与drop截然相反的
prefix(while: {})
当接收到3的时候可以理解成直接发送了finished
let numbers = (1...10).publisher
numbers.prefix(while: {
print("x")
return $0 < 3
}).sink(receiveCompletion: { print("Completed with: \($0)") }, receiveValue: { print($0) }).store(in: &subscriptions)
/*
x
x
x
1
2
Completed with: finished
*/
prefix(untilOutputFrom: isReady)
let isReady = PassthroughSubject<Void, Never>()
let taps = PassthroughSubject<Int, Never>()
taps.prefix(untilOutputFrom: isReady).sink(receiveCompletion: { print("Completed with: \($0)") }, receiveValue: { print($0) }).store(in: &subscriptions)
(1...5).forEach { n in
taps.send(n)
if n == 2 {
isReady.send()
}
}