美文网首页
combine - Filtering Operators

combine - Filtering Operators

作者: 追忆之丘 | 来源:发表于2021-07-18 20:05 被阅读0次

filter{ $o.isMultiple(of: 3) }

筛选出3的倍数


image.png
    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

image.png

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值


image.png
    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

image.png
    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:{})

image.png
    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:{})

image.png

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()

image.png

考过前3个,直到第四个开始sink

    let number = (1...10).publisher

    number.dropFirst(8).sink(receiveValue: { print($0) }).store(in: &subscriptions)
    /// 9
    /// 10

drop(while:)

image.png

直到第一个满足条件的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:)

image.png

很容易从字面去理解这个函数的功能,直到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(_:)

image.png

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: {})

image.png

当接收到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)

image.png
     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()
        }
    }

相关文章

网友评论

      本文标题:combine - Filtering Operators

      本文链接:https://www.haomeiwen.com/subject/ujwapltx.html