iOS開發(fā)進階 - RxSwift :Filter相關操作

前言

萬丈高樓平地起国葬,前面兩篇地基已經(jīng)建好宴树,現(xiàn)在開始第一層国章。
示例代碼請移步Github
RxSwift 4.4

從本篇開始接下來幾篇文章會詳細學習 RxSwiftOperators愿阐,作為 Rx編程的基石才写,可以使用它來轉(zhuǎn)換竹挡,處理和響應事件镀娶。

Operators 分為四個部分:

  • Filtering Operators:過濾
  • Transforming Operators : 轉(zhuǎn)換
  • Combing Operators : 組合
  • Time-Based Operators : 基于時間操作

接下來學習過濾相關的操作。

Filtering Operators

過濾操作分為四類:

分類 主要方法 說明
Ignoring Operators ignoreElements elementAt filter 用于忽略一些元素
Skipping Operators skip skipWhile skipUntil
Taking Operators take takeWhile takeUntil
Distinct Operators distinctUntilChange distinctUntilChanged(_:)

從整體上了解要學習的內(nèi)容揪罕,接下來詳細分析各個操作作用梯码,特點及區(qū)別聯(lián)系。

Ignoring Operators

ignoreElements

特點:忽略所有的 .next 事件元素好啰,允許終止事件通過轩娶。如:.completed.error。是不是應該想起來什么框往?ignoreElements 實際上返回一個 Completable鳄抒。

raywenderlich.com

①:表示源序列,可以被訂閱
②:表示操作及參數(shù)
③:訂閱

實例代碼:

/// 1. ignoreElements : 忽略所有的 .next 事件元素搅窿,允許停止事件通過嘁酿,如 .completed 和 .error.
/// 也許會發(fā)現(xiàn):ignoreElements 實際上返回一個 Completable
example(of: "ignoreElements") {
    // 1. 創(chuàng)建 subject
    let strikes = PublishSubject<String>()
    let disposeBag = DisposeBag()
    // 2. 添加訂閱
    strikes
        .ignoreElements() // 忽略所有元素
        .subscribe{_ in
            print("You are out!")
        }
        .disposed(by: disposeBag)
    
    strikes.onNext("X") // 無輸出
    strikes.onNext("Y") // 無輸出
    
    strikes.onCompleted() // 輸出 You are out!
}

elementAt

特點: 獲取指定位置的元素。只要獲取到指定位置的元素男应,訂閱就終止闹司。

raywenderlich.com

示例代碼:

/// 2. elementAt : 獲取指定位置的元素。
/// 只要獲取到指定位置的元素沐飘,訂閱就終止游桩。
example(of: "elementAt") {
    let strikes = PublishSubject<String>()
    let bag = DisposeBag()
    
    strikes
        .elementAt(2) // 獲取序列中 index = 2 的元素
        .subscribe(onNext: { element in
            print("\(element) - You are out!")
        })
        .disposed(by: bag)
    strikes.onNext("X") // 無輸出
    strikes.onNext("Y") // 無輸出
    strikes.onNext("Z") // index = 2 輸出
    
    // 輸出:Z - You are out!
}

filter

特點:ignoreElementelementAt 過濾序列元素。有時不針對全部或單個元素操作耐朴。filter 提供了一個閉包借卧,針對所有的元素,只要滿足添加就可以輸出筛峭。

raywenderlich.com

示例代碼:

/// 3. ignoreElement 和 elementAt 過濾序列元素铐刘。有時不針對全部或單個元素操作。
/// filter 提供了一個閉包影晓,針對所有的元素镰吵,只要滿足添加就可以輸出檩禾。
example(of: "filter") {
    let bag = DisposeBag()
    // 1. 創(chuàng)建一個序列
    Observable.of(1, 2, 3, 4, 5, 6)
        .filter{ $0 % 2 == 0} // 2. 過濾偶數(shù)
        .subscribe(onNext: { // 3. 訂閱
            print($0)
        })
        .disposed(by: bag)
    // 輸出: 2 4 6
}

Transforming Operators

skip

特點: 跳過指定數(shù)量的元素。

示例代碼:

/// 1. skip() : 跳過指定數(shù)量的元素

example(of: "skip") {
    let bag = DisposeBag()
    
    // 1. 序列
    Observable.of("A", "B", "C", "D", "E", "F")
        .skip(3) // 2. 跳過三個元素
        .subscribe( onNext: { // 3. 訂閱
            print($0)
        })
        .disposed(by: bag)
    // 輸出: D E F
}

skipWhile

/// 2. skipWhile : 像 skip 一樣決定哪些元素被忽略疤祭。
/// skipWhile 只跳過元素盼产,直到第一個元素被允許通過,然后所有剩余的元素都被允許通過勺馆。
/// 閉包 返回 true 對應的元素將被忽略戏售;返回 false 對應的元素通過。
/// 與 filter 操作相反草穆。
example(of: "skipWhile") {
    let bag = DisposeBag()
    
    Observable.of(2, 2, 3, 4, 4) // 1. 序列
        .skipWhile { $0 % 2 == 0} // 2. 跳過 開始時的 偶數(shù)
        .subscribe(onNext: {
            print($0)
        })
        .disposed(by: bag)
    // 輸出: 3 4 4
}

skipUntil

/// 以上都是靜態(tài)的條件過濾元素灌灾,如果想基于其他序列動態(tài)過濾元素怎么辦?
/// 3. skipUntil : 它將保持跳過原序列所有元素悲柱,直到觸發(fā)序列發(fā)射 .next 事件紧卒,開始輸出后續(xù)元素。
example(of: "skipUntil") {
    let bag = DisposeBag()
    // 1. 一個源序列诗祸,一個觸發(fā)序列
    let subject = PublishSubject<String>()
    let trigger = PublishSubject<String>()
    
    // 2.
    subject
        .skipUntil(trigger) // 直到 trigger 序列有 .next 事件
        .subscribe(onNext: {
            print($0)
        })
        .disposed(by: bag)
    
    subject.onNext("A")
    subject.onNext("B") // 未輸出
    trigger.onNext("X") // 觸發(fā)
    subject.onNext("C")
    
    // 輸出:C
}

Taking Operators

take

/// Taking 是與 Skipping 相反的操作。
/// 1. take: 獲取幾個元素
example(of: "take") {
    let bag  = DisposeBag()
    
    Observable.of(4, 5, 6, 7, 8, 9)
        .take(3) // 獲取三個元素
        .subscribe(onNext: {
            print($0)
        })
        .disposed(by: bag)
    // 輸出: 4 5 6
}

takeWhile

/// 2. takeWhile: 與 skipWhile 類似轴总,不同點是用 taking 代替 skipping
example(of: "takeWhile") {
    let bag = DisposeBag()
    
    Observable.of(2, 2, 4, 4, 6, 6)
        .enumerated() // 1. 獲取元組包含 index 和 element
        .takeWhile({ index, integer in // 2. 直到條件不成立停止
            integer % 2 == 0 && index < 3
        })
        .map { $0.element } // 3. 獲取元素直颅,生成只包含元素的序列
        .subscribe(onNext: { // 4. 訂閱輸出
            print($0)
        })
        .disposed(by: bag)
    
    // 輸出: 2 2 4
}

takeUntil

/// 3. takeUntil: 與 skipUntil 類似
/// 持續(xù)獲取源序列中元素,直到觸發(fā)序列發(fā)送 .next 事件怀樟。
example(of: "takeUntil") {
    let bag = DisposeBag()
    // 1.
    let subject = PublishSubject<String>()
    let trigger = PublishSubject<String>()
    
    // 2.
    subject
        .takeUntil(trigger)
        .subscribe(onNext: {
            print($0)
        })
        .disposed(by: bag)
    // 3.
    subject.onNext("A")
    subject.onNext("B")
    trigger.onNext("1") // 觸發(fā)序列終止源序列
    subject.onNext("C")
    // 輸出:A B
    // 思考:是不是可以通過 takeUntil 監(jiān)控 VC 的銷毀功偿。
}

Distinct Operators

distinctUntilChanged

/// 1. distinctUntilChanged : 阻止下一個重復元素
/// 只阻止相鄰重復元素。
example(of: "distinctUntilChanged") {
    let bag = DisposeBag()
    
    Observable.of("A", "A", "B", "B", "A")
        .distinctUntilChanged()
        .subscribe(onNext: {
            print($0)
        })
        .disposed(by: bag)
    // 輸出:A B A
}

distinctUntilChanged(_:)

/// 2. distinctUntilChanged(_:) 自定義比較
example(of: "distinctUntilChanged(_:)") {
    let bag = DisposeBag()
    // 1
    let formatter = NumberFormatter()
    formatter.numberStyle = .spellOut // 朗讀形式往堡,英文械荷,例如:110 ==> ["one", "hundred", "ten"]
    // 2. 序列
    Observable<NSNumber>.of(10, 110, 20, 200, 210, 310)
        // 3
        .distinctUntilChanged { a, b in
            guard let aWords = formatter.string(from: a)?.components(separatedBy: " "),
            let bWords = formatter.string(from: b)?.components(separatedBy: " ")
            else {return false}
            print(aWords, bWords)
            var containsMatch = false
            for aWord in aWords where bWords.contains(aWord) {
                containsMatch = true
                break
            }
            return containsMatch
            /*
             第一次:["ten"] ["one", "hundred", "ten"] ==> true, 跳過 110
             第二次:["ten"] ["twenty"] ==> false
             第三次:["twenty"] ["two", "hundred"] ==> false
             第四次:["two", "hundred"] ["two", "hundred", "ten"] ==> true,跳過 210
             第五次:["two", "hundred"] ["three", "hundred", "ten"] ==> true, 跳過 310
             */
            
        }
        // 訂閱
        .subscribe(onNext: {
            print($0)
        })
        .disposed(by: bag)
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末虑灰,一起剝皮案震驚了整個濱河市吨瞎,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌穆咐,老刑警劉巖颤诀,帶你破解...
    沈念sama閱讀 206,126評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異对湃,居然都是意外死亡崖叫,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,254評論 2 382
  • 文/潘曉璐 我一進店門拍柒,熙熙樓的掌柜王于貴愁眉苦臉地迎上來心傀,“玉大人,你說我怎么就攤上這事拆讯≈校” “怎么了养叛?”我有些...
    開封第一講書人閱讀 152,445評論 0 341
  • 文/不壞的土叔 我叫張陵,是天一觀的道長疆液。 經(jīng)常有香客問我一铅,道長,這世上最難降的妖魔是什么堕油? 我笑而不...
    開封第一講書人閱讀 55,185評論 1 278
  • 正文 為了忘掉前任潘飘,我火速辦了婚禮,結(jié)果婚禮上掉缺,老公的妹妹穿的比我還像新娘卜录。我一直安慰自己,他們只是感情好眶明,可當我...
    茶點故事閱讀 64,178評論 5 371
  • 文/花漫 我一把揭開白布艰毒。 她就那樣靜靜地躺著,像睡著了一般搜囱。 火紅的嫁衣襯著肌膚如雪丑瞧。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 48,970評論 1 284
  • 那天蜀肘,我揣著相機與錄音绊汹,去河邊找鬼。 笑死扮宠,一個胖子當著我的面吹牛西乖,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播坛增,決...
    沈念sama閱讀 38,276評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼获雕,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了收捣?” 一聲冷哼從身側(cè)響起届案,我...
    開封第一講書人閱讀 36,927評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎罢艾,沒想到半個月后萝玷,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,400評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡昆婿,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,883評論 2 323
  • 正文 我和宋清朗相戀三年球碉,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片仓蛆。...
    茶點故事閱讀 37,997評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡睁冬,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情豆拨,我是刑警寧澤直奋,帶...
    沈念sama閱讀 33,646評論 4 322
  • 正文 年R本政府宣布,位于F島的核電站施禾,受9級特大地震影響脚线,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜弥搞,卻給世界環(huán)境...
    茶點故事閱讀 39,213評論 3 307
  • 文/蒙蒙 一邮绿、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧攀例,春花似錦船逮、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,204評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至梆惯,卻和暖如春酱鸭,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背垛吗。 一陣腳步聲響...
    開封第一講書人閱讀 31,423評論 1 260
  • 我被黑心中介騙來泰國打工凛辣, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人职烧。 一個月前我還...
    沈念sama閱讀 45,423評論 2 352
  • 正文 我出身青樓,卻偏偏與公主長得像防泵,于是被迫代替她去往敵國和親蚀之。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 42,722評論 2 345

推薦閱讀更多精彩內(nèi)容

  • Introduction: Creating and Subscribing to Observables: Th...
    loongod閱讀 732評論 0 0
  • Operators是RxSwift的基本組成部分捷泞,它的重要性就不言而喻了足删,前面只是提到在我們開發(fā)中,當收到obse...
    ripple_k閱讀 1,414評論 2 8
  • RxJava技術分享 京金所—時光 2016.9.22 這里我拿出來給 Android 開發(fā)者的 RxJava 詳...
    JC_Mobile閱讀 5,562評論 3 55
  • 前言 按照官方的分類锁右,操作符大致分為以下幾種: Creating Observables(Observable的創(chuàng)...
    小玉1991閱讀 1,040評論 0 1
  • 文字有言情失受、說理、敘事咏瑟、狀物四大功用拂到,在文學的文字中,無論是說理码泞、敘事兄旬、狀物,都必須流露一種情致余寥,若不然领铐,那就...
    飛鳥逐溪閱讀 360評論 0 0