RxSwift(七) - 变换操作符(buffer、map、flatMap、scan等)

变换操作符

变换操作符是指对原始的 Observable 序列进行一些变换.

1. buffer

(1) 简介

  • buffer 方法的作用是缓冲组合, 第一个参数是缓冲时间, 第二个参数是缓冲个数, 第三个是参数是线程
  • buffer 的作用就是缓存 Observable 中发出的元素, 当元素达到某个数量, 或者经过指定时间, 它就会将这个元素集合发送出来.
buffer.png

(2) 案例

let disposeBag = DisposeBag()
        
let subject = PublishSubject<String>()
//每缓存三个元素,则组合起来一起发出
//如果一秒钟内不够三个也会发出(有几个发几个, 一个没有就发送空数组)
subject.buffer(timeSpan: 1, count: 3, scheduler: MainScheduler.instance)
.subscribe(onNext: { print($0) })
.disposed(by: disposeBag)
        
subject.onNext("a")
subject.onNext("b")
subject.onNext("c")
        
subject.onNext("11")
subject.onNext("22")
subject.onNext("33")

//输出结果
["a", "b", "c"]
["11", "22", "33"]
2. window

(1) 简介

  • window 操作符和 buffer 十分相似. buffer 是周期性的将缓存的元素集合发送出来, 而 window 是周期性的将元素集合以 Observable 的形态发送出来
  • buffer 要等元素搜集完毕后,才会发出元素序列. 而 window 可以实时发出元素序列.
    window.png

(2) 案例

let disposeBag = DisposeBag()
        
let subject = PublishSubject<String>()
subject.window(timeSpan: 1, count: 3, scheduler: MainScheduler.instance)
.subscribe(onNext: { [weak self] in
    print("subscribe: \($0)")
    $0.asObservable()
    .subscribe(onNext: { print($0) })
    .disposed(by: disposeBag)
})
.disposed(by: disposeBag)
        
subject.onNext("a")
subject.onNext("b")
subject.onNext("c")
         
subject.onNext("1")
subject.onNext("2")
subject.onNext("3")

//输出结果
subscribe: RxSwift.AddRef<Swift.String>
a
b
c
subscribe: RxSwift.AddRef<Swift.String>
1
2
3
subscribe: RxSwift.AddRef<Swift.String>
subscribe: RxSwift.AddRef<Swift.String>
...
3. map

(1) 简介

  • 该操作符通过传入一个函数闭包把原来的 Observable 序列转变成一个新的 Observable 序列
    map.png

(2) 案例

let disposeBag = DisposeBag()
        
Observable.of(1,2,3)
.map {$0 * 10}
.subscribe(onNext: { print($0) })
.disposed(by: disposeBag)

//输出结果
10
20
30
4. flatMap

(1) 简介

  • flatMap 操作符会对源 Observable 的每一个元素应用一个转换方法, 将他们转换成 Observables, 然后将这些 Observables 的元素合并之后再发出来
    flatMap.png

(2) 案例

let disposeBag = DisposeBag()
        
let first = BehaviorSubject(value: "1")
let second = BehaviorSubject(value: "A")
        
let be = Variable(first)
be.asObservable()
.flatMap { $0 }
.subscribe(onNext: { print($0) }) //订阅发送上一个event,即默认值
.disposed(by: disposeBag)
        
first.onNext("2") //发出event 2
be.value = second   //订阅second
second.onNext("B")  //发出event B
first.onNext("3")   //发出event 3

//输出结果
1
2
A
B
3
5. flatMapLatest

(1) 简介

  • flatMapLatestflatMap 的唯一区别是: flatMapLatest 只会接收最新的 value 事件
    flatMapLatest.png

(2) 案例

let disposeBag = DisposeBag()
        
let first = BehaviorSubject(value: "1")
let second = BehaviorSubject(value: "A")
        
let be = Variable(first)
be.asObservable()
.flatMapLatest { $0 }
.subscribe(onNext: { print($0) }) //订阅发送上一个event,即默认值
.disposed(by: disposeBag)
        
first.onNext("2") //发出event 2
be.value = second   //订阅second
second.onNext("B")  //发出event B
first.onNext("3")   //现在value为 second , 所以不会发出event

//输出结果
1
2
A
B
6. flatMapFirst

(1) 简介

  • flatMapFirstflatMapLatest正好相反, flatMapFirst 只会接收最初的 value 事件

(2) 案例

let disposeBag = DisposeBag()
        
let first = BehaviorSubject(value: "1")
let second = BehaviorSubject(value: "A")
        
let be = Variable(first)
be.asObservable()
.flatMapFirst { $0 }
.subscribe(onNext: { print($0) }) //订阅发送上一个event,即默认值
.disposed(by: disposeBag)
        
first.onNext("2") //发出event 2
be.value = second   //订阅second
second.onNext("B")  //只会发出最初value的event
first.onNext("3")   //发出3

//输出结果
1
2
3
7. concatMap

(1) 简介

  • concatMapflatMap的唯一区别是: 当前一个 Observable 元素发送完毕后, 后一个 Observable 才可以开始发出元素, 或者说等待前一个 Observable 产生完成事件后, 才对后一个 Observable 进行订阅
    concatMap.png

(2) 案例

let disposeBag = DisposeBag()
        
let first = BehaviorSubject(value: "1")
let second = BehaviorSubject(value: "A")
        
let be = Variable(first)
be.asObservable()
.concatMap { $0 }
.subscribe(onNext: { print($0) }) //订阅发送上一个event,即默认值
.disposed(by: disposeBag)
        
first.onNext("2") //发出event 2
be.value = second   //first未完结,只做订阅,不发出event
second.onNext("B")  //first未完结,等待处理
first.onNext("3")   //现在value为 second , 所以不会发出event
first.onCompleted(); //first完结,处理发出的event

//输出结果
1
2
3
B
8. scan

(1) 简介

  • scan 就是先给一个初始化的数, 然后不断拿前一个结果和最新的值进行处理操作
  • scan 操作符将对第一个元素应用一个函数,将结果作为第一个元素发出。然后,将结果作为参数填入到第二个元素的应用函数中,创建第二个元素。以此类推,直到遍历完全部的元素。
    (2) 案例
let disposeBag = DisposeBag()
        
Observable.of(1,2,3,4)
.scan(0) { (a, b) -> Int in
    return a + b
}.subscribe(onNext: { print($0) })
.disposed(by: disposeBag)

//输出结果
1
3
6
10
9. groupBy

(1) 简介

  • groupBy 操作符将源 Observable 分解为多个子 Observable, 然后将这些子 Observable 发送出来. 即 该操作符会根据某个条件对源 Observable 序列进行分组, 在讲分组后的元素以 Observable 的形态发送出来
    groupBy.png

(2) 案例

let disposeBag = DisposeBag()
        
Observable<Int>.of(0,1,2,3,4,5)
.groupBy { (element) -> String in
    return element % 2 == 0 ? "偶数" : "奇数"
}
.subscribe { event in
    switch event {
        case .next(let group):
        group.asObservable().subscribe { (event) in
        print("key: \(group.key)   event: \(event)" )
    }
    .disposed(by: disposeBag)
        default:
            print("")
    }
}
.disposed(by: disposeBag)

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

推荐阅读更多精彩内容