Update Combining Operators and move before Transforming Operators

This commit is contained in:
Scott Gardner 2016-05-13 14:01:43 -05:00
parent a68c07beb5
commit 38dec119e9
4 changed files with 127 additions and 255 deletions

View File

@ -9,278 +9,150 @@
*/
import RxSwift
/*:
## Combination Operators
Operators that work with multiple source Observables to create a single Observable.
*/
/*:
### `startWith`
emit a specified sequence of items before beginning to emit the items from the source Observable
# Combination Operators
Operators that combine multiple source `Observable`s into a single `Observable`.
## `startWith`
Emits the specified sequence of elements before beginning to emit the elements from the source `Observable`. [More info](http://reactivex.io/documentation/operators/startwith.html)
![](https://raw.githubusercontent.com/kzaher/rxswiftcontent/master/MarbleDiagrams/png/startwith.png)
[More info in reactive.io website]( http://reactivex.io/documentation/operators/startwith.html )
*/
example("startWith") {
let disposeBag = DisposeBag()
let subscription = Observable.of("🐶","🐱","🐭","🐹")
.startWith("🔴")
.startWith("🅱️")
.startWith("🆎")
.subscribe {
print($0)
}
Observable.of("🐶", "🐱", "🐭", "🐹")
.startWith("1")
.startWith("2")
.startWith("3", "🅰️", "🅱️")
.subscribeNext { print($0) }
.addDisposableTo(disposeBag)
}
/*:
### `combineLatest`
> As this example demonstrates, `startWith` can be chained on a last-in-first-out basis, i.e., each successive `startWith`'s elements will be prepended before the prior `startWith`'s elements.
## `merge`
Combines elements from source `Observable` sequences into a single new `Observable` sequence, and will emit each element as it is emitted by each source `Observable` sequence. [More info](http://reactivex.io/documentation/operators/merge.html)
![](https://raw.githubusercontent.com/kzaher/rxswiftcontent/master/MarbleDiagrams/png/merge.png)
*/
example("merge") {
let disposeBag = DisposeBag()
when an item is emitted by either of two Observables, combine the latest item emitted by each Observable via a specified function and emit items based on the results of this function
![](https://raw.githubusercontent.com/kzaher/rxswiftcontent/master/MarbleDiagrams/png/combinelatest.png)
[More info in reactive.io website]( http://reactivex.io/documentation/operators/combinelatest.html )
*/
example("combineLatest 1") {
let stringObs = PublishSubject<String>()
let intObs = PublishSubject<Int>()
_ = Observable.combineLatest(stringObs, intObs) {
"\($0) \($1)"
}
.subscribe {
print($0)
}
stringObs.on(.Next("🅰️"))
intObs.on(.Next(1))
stringObs.on(.Next("🅱️"))
intObs.on(.Next(2))
}
//: To produce output, at least one element has to be received from each sequence in arguements.
example("combineLatest 2") {
let stringObs = Observable.of("🐶","🐱","🐭","🐹")
let intObs = Observable.just(2)
_ = Observable.combineLatest(stringObs, intObs) {
"\($0) \($1)"
}
.subscribe {
print($0)
}
}
//: Combine latest has versions with more than 2 arguments.
example("combineLatest 3") {
let intObs = Observable.just(2)
let stringObs1 = Observable.of("🐶","🐱","🐭","🐹")
let stringObs2 = Observable.of("🅰️","🅱️","🆎")
_ = Observable.combineLatest(intObs, stringObs1, stringObs2) {
"\($0) \($1) \($2)"
}
.subscribe {
print($0)
}
}
//: Combinelatest version that allows combining sequences with different types.
example("combineLatest 4") {
let intObs = Observable.just(2)
let stringObs = Observable.just("🔴")
_ = Observable.combineLatest(intObs, stringObs) {
"\($0) " + $1
}
.subscribe {
print($0)
}
}
//: `combineLatest` extension method for Array of `ObservableType` conformable types
//: The array must be formed by `Observables` of the same type.
example("combineLatest 5") {
let stringObs1 = Observable.just("❤️")
let stringObs2 = Observable.of("🐶","🐱","🐭","🐹")
let stringObs3 = Observable.of("🅰️","🅱️","🆎")
_ = [stringObs1, stringObs2, stringObs3].combineLatest { stringArray -> String in
stringArray[0] + stringArray[1] + stringArray[2]
}
.subscribe { (event: Event<String>) -> Void in
print(event)
}
}
/*:
### `zip`
combine the emissions of multiple Observables together via a specified function and emit single items for each combination based on the results of this function
![](https://raw.githubusercontent.com/kzaher/rxswiftcontent/master/MarbleDiagrams/png/zip.png)
[More info in reactive.io website](http://reactivex.io/documentation/operators/zip.html)
*/
example("zip 1") {
let stringObs = PublishSubject<String>()
let intObs = PublishSubject<Int>()
_ = Observable.zip(stringObs, intObs) {
"\($0) \($1)"
}
.subscribe {
print($0)
}
stringObs.on(.Next("🔴"))
intObs.on(.Next(1))
stringObs.on(.Next("🔵"))
stringObs.on(.Next("⚪️"))
intObs.on(.Next(2))
}
example("zip 2") {
let intObs = Observable.just(1)
let stringObs = Observable.of("🐶","🐱","🐭","🐹")
_ = Observable.zip(intObs, stringObs) {
"\($0) \($1)"
}
.subscribe {
print($0)
}
}
example("zip 3") {
let intObs = Observable.of(1,2)
let stringObs1 = Observable.of("🐶","🐱","🐭","🐹")
let stringObs2 = Observable.of("🍎","🍐","🍊","🍋","🍉","🍓")
_ = Observable.zip(intObs, stringObs1, stringObs2) {
"\($0) \($1) \($2)"
}
.subscribe {
print($0)
}
}
/*:
### `merge`
combine multiple Observables into one by merging their emissions
![](https://raw.githubusercontent.com/kzaher/rxswiftcontent/master/MarbleDiagrams/png/merge.png)
[More info in reactive.io website]( http://reactivex.io/documentation/operators/merge.html )
*/
example("merge 1") {
let subject1 = PublishSubject<String>()
let subject2 = PublishSubject<String>()
_ = Observable.of(subject1, subject2)
Observable.of(subject1, subject2)
.merge()
.subscribeNext { string in
print(string)
}
.subscribeNext { print($0) }
.addDisposableTo(disposeBag)
subject1.on(.Next("🍎"))
subject1.on(.Next("🍐"))
subject1.on(.Next("🍊"))
subject2.on(.Next("🔴"))
subject1.on(.Next("🍋"))
subject1.on(.Next("🍉"))
subject2.on(.Next("🔵"))
subject1.onNext("🅰️")
subject1.onNext("🅱️")
subject2.onNext("")
subject2.onNext("")
subject1.onNext("🆎")
subject2.onNext("")
}
example("merge 2") {
let subject1 = PublishSubject<String>()
let subject2 = PublishSubject<String>()
_ = Observable.of(subject1, subject2)
.merge(maxConcurrent: 2)
.subscribe {
print($0)
}
subject1.on(.Next("🍎"))
subject1.on(.Next("🍐"))
subject1.on(.Next("🍊"))
subject2.on(.Next("🔴"))
subject1.on(.Next("🍋"))
subject1.on(.Next("🍉"))
subject2.on(.Next("🔵"))
}
/*:
### `switchLatest`
## `zip`
Combines up to 8 source `Observable` sequences into a single new `Observable` sequence, and will emit from the combined `Observable` sequence the elements from each of the source `Observable` sequences at the corresponding index. [More info](http://reactivex.io/documentation/operators/zip.html)
![](https://raw.githubusercontent.com/kzaher/rxswiftcontent/master/MarbleDiagrams/png/zip.png)
*/
example("zip") {
let disposeBag = DisposeBag()
convert an Observable that emits Observables into a single Observable that emits the items emitted by the most-recently-emitted of those Observables
let stringSubject = PublishSubject<String>()
let intSubject = PublishSubject<Int>()
![](https://raw.githubusercontent.com/kzaher/rxswiftcontent/master/MarbleDiagrams/png/switch.png)
[More info in reactive.io website]( http://reactivex.io/documentation/operators/switch.html )
*/
example("switchLatest") {
let var1 = Variable("⚽️")
let var2 = Variable("🍎")
// var3 is an Observable<Observable<String>>
let var3 = Variable(var1.asObservable())
let d = var3
.asObservable()
.switchLatest()
.subscribe {
print($0)
Observable.zip(stringSubject, intSubject) { stringElement, intElement in
"\(stringElement) \(intElement)"
}
.subscribeNext { print($0) }
.addDisposableTo(disposeBag)
var1.value = "🏀"
var1.value = "🏈"
var1.value = "⚾️"
var1.value = "🎱"
stringSubject.onNext("🅰️")
stringSubject.onNext("🅱️")
var3.value = var2.asObservable()
intSubject.onNext(1)
var2.value = "🍐"
intSubject.onNext(2)
var1.value = "🏐"
var1.value = "🏉"
var2.value = "🍋"
stringSubject.onNext("🆎")
intSubject.onNext(3)
}
/*:
----
## `combineLatest`
Combines up to 8 source `Observable` sequences into a single new `Observable` sequence, and will begin emitting from the combined `Observable` sequence the latest elements of each source `Observable` sequence once all source sequences have emitted at least one element, and also when any of the source `Observable` sequences emits a new element. [More info](http://reactivex.io/documentation/operators/combinelatest.html)
![](https://raw.githubusercontent.com/kzaher/rxswiftcontent/master/MarbleDiagrams/png/combinelatest.png)
*/
example("combineLatest") {
let disposeBag = DisposeBag()
let stringSubject = PublishSubject<String>()
let intSubject = PublishSubject<Int>()
Observable.combineLatest(stringSubject, intSubject) { stringElement, intElement in
"\(stringElement) \(intElement)"
}
.subscribeNext { print($0) }
.addDisposableTo(disposeBag)
stringSubject.onNext("🅰️")
stringSubject.onNext("🅱️")
intSubject.onNext(1)
intSubject.onNext(2)
stringSubject.onNext("🆎")
}
//: There is also a `combineLatest` extension on `Array`:
example("Array.combineLatest") {
let disposeBag = DisposeBag()
let stringObservable = Observable.just("❤️")
let fruitObservable = ["🍎", "🍐", "🍊"].toObservable()
let animalObservable = Observable.of("🐶", "🐱", "🐭", "🐹")
[stringObservable, fruitObservable, animalObservable].combineLatest {
"\($0[0]) \($0[1]) \($0[2])"
}
.subscribeNext { print($0) }
.addDisposableTo(disposeBag)
}
/*:
> The `combineLatest` extension on `Array` requires that all source `Observable` sequences are of the same type.
----
## `switchLatest`
Transforms the elements emitted by an `Observable` sequence into `Observable` sequences, and emits elements from the most recent inner `Observable` sequence. [More info](http://reactivex.io/documentation/operators/switch.html)
![](https://raw.githubusercontent.com/kzaher/rxswiftcontent/master/MarbleDiagrams/png/switch.png)
*/
example("switchLatest") {
let disposeBag = DisposeBag()
let subject1 = BehaviorSubject(value: "⚽️")
let subject2 = BehaviorSubject(value: "🍎")
let variable = Variable(subject1)
variable.asObservable()
.switchLatest()
.subscribeNext { print($0) }
.addDisposableTo(disposeBag)
subject1.onNext("🏈")
subject1.onNext("🏀")
variable.value = subject2
subject1.onNext("⚾️")
subject2.onNext("🍐")
}
/*:
> In this example, adding onto `subject1` after setting `variable.value` to `subject2` has no effect, because only the most recent inner `Observable` sequence (`subject2`) will emit elements.
*/
//: [Next](@next) - [Table of Contents](Table_of_Contents)

View File

@ -9,9 +9,9 @@
1. [Introduction](Introduction)
1. [Creating and Subscribing to Observables](Creating_and_Subscribing_to_Observables)
1. [Working with Subjects](Working_with_Subjects)
1. [Combining Operators](Combining_Operators)
1. [Transforming Operators](Transforming_Operators)
1. [Filtering Operators](Filtering_Operators)
1. [Combining Operators](Combining_Operators)
1. [Conditional Operators](Conditional_Operators)
1. [Mathematical and Aggregate Operators](Mathematical_and_Aggregate_Operators)
1. [Connectable Operators](Connectable_Operators)

View File

@ -54,7 +54,7 @@ example("flatMap and flatMapLatest") {
👧🏼.score.value = 100
}
/*:
> In the above example, using `flatMap` may have unintended consequences. After assigning 👧🏼 to `player.value`, `👧🏼.score` will begin to emit elements, but the previous inner `Observable` sequence (`👦🏻.score`) will also still emit elements. By changing `flatMap` to `flatMapLatest`, only the most recent inner `Observable` sequence (`👧🏼.score`) will emit elements, i.e., setting `👦🏻.score.value` to `95` has no effect.
> In this example, using `flatMap` may have unintended consequences. After assigning 👧🏼 to `player.value`, `👧🏼.score` will begin to emit elements, but the previous inner `Observable` sequence (`👦🏻.score`) will also still emit elements. By changing `flatMap` to `flatMapLatest`, only the most recent inner `Observable` sequence (`👧🏼.score`) will emit elements, i.e., setting `👦🏻.score.value` to `95` has no effect.
#
> `flatMapLatest` is actually a combination of the `map` and `switchLatest` operators.
*/

View File

@ -5,9 +5,9 @@
<page name='Introduction'/>
<page name='Creating_and_Subscribing_to_Observables'/>
<page name='Working_with_Subjects'/>
<page name='Combining_Operators'/>
<page name='Transforming_Operators'/>
<page name='Filtering_Operators'/>
<page name='Combining_Operators'/>
<page name='Conditional_Operators'/>
<page name='Mathematical_and_Aggregate_Operators'/>
<page name='Connectable_Operators'/>