combine - Filtering Operators

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()
        }
    }
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,692评论 6 501
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,482评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,995评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,223评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,245评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,208评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,091评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,929评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,346评论 1 311
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,570评论 2 333
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,739评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,437评论 5 344
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,037评论 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,677评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,833评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,760评论 2 369
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,647评论 2 354

推荐阅读更多精彩内容