preface

In RxSwift, higher-order functions can also be operators, which can help us create new sequences or combine existing sequences to generate a new sequence.

Conversion operator

1. map

The Map operator converts the original Observable sequence into a new Observable by passing in a function closure. The Map function converts all elements of the source sequence and returns a new sequence.

Example:

    let disposeBag = DisposeBag()
 
    Observable.of(1, 2, 3)
        .map { $0 * 100}
        .subscribe(onNext: { print($0Disposed (by: disposeBag) // Result: 100 200 300Copy the code

2. flatMap

Map is prone to “raise dimensions” during transformation. That is, after the transformation, you go from a sequence to a sequence of sequences. The flatMap operator, on the other hand, applies a transform method to each element of the source Observable, converting them to Observables. The elements of the Observables are then merged and sent out. Reduces the dimension to an Observable sequence.

Observable
Observable
Observables

Example:

    let disposeBag = DisposeBag()
    let Henry = BehaviorSubject(value: 1)
    let Jeannie = BehaviorSubject(value: 2)
    let Henry_Subject = BehaviorSubject(value: Henry)

    Henry_Subject.asObservable()
          .flatMap { $0 }
          .subscribe(onNext: { print($0) }) .disposed(by: OnNext (3) henry_subject.onNext (Jeannie) Henry. OnNext (5) Jeannie. OnNext (6) // Result 1 3 2 5 6Copy the code

3. flatMapLatest

The flatMapLatest operator converts Observable elements to other Observables and fetches the latest of these Observables.

flatMapLatest
Observable
Observables
Observable
Observables

  • flatMapLatestwithflatMapThe only difference is:flatMapLatestOnly the latest ones will be acceptedvalueEvents.
  • flatMapLatestIs, in fact,mapandswitchLatestA combination of operators
  • There areflatMapLatestThere will beflatMapFirst.flatMapFirstwithflatMapLatestOn the contrary:flatMapFirstOnly the original will be acceptedvalueEvents. (This operator prevents repeated requests: clicking a button to send a request, for example, should not continue until the request is complete. Can be usedflatMapFirstOperator.

Example:

    let disposeBag = DisposeBag()
    let Henry = BehaviorSubject(value: 1)
    let Jeannie = BehaviorSubject(value: 2)
    let Henry_Subject = BehaviorSubject(value: Henry)
        
    Henry_Subject.asObservable()
        .flatMapLatest{ $0 }
        .subscribe(onNext: { print($0) }) .disposed(by: OnNext (3) henry_subject.onNext (Jeannie) Jeanny.onnext (5) henry.onNext (6) // Result: 1 3 2 5Copy the code

4. concatMap

The concatMap operator converts Observable elements to other Observables, and then concatenates them

concatMap
Observable
Observables
Observables

  • concatMapflatMapThe only difference is: the current oneObservableAfter the element is sent, the last oneObservableBefore you can start emitting elements. Wait for the previous oneObservableThe last one is generated after the completion eventObservableSubscribe.

Example:

    let disposeBag = DisposeBag()
    let Henry = BehaviorSubject(value: 1)
    let Jeannie = BehaviorSubject(value: 2)
    let Henry_Subject = BehaviorSubject(value: Henry)
        
    Henry_Subject.asObservable()
        .concatMap{ $0 }
        .subscribe(onNext: { print($0) }) .disposed(by: OnNext (5) Jeannie. OnNext (6) Henry. OnCompleted () // Result: 1 3 6Copy the code

5. scan

The Scan operator continuously converts Observable and emits the result of each function return

scan
scan

Example:

    let disposeBag = DisposeBag()

    Observable.of(1, 2, 3, 4, 5)
        .scan(0) { acum, elem in
        acum + elem
    }
        .subscribe(onNext: { print($0Disposed (by: disposeBag) // Result 1 3 6Copy the code

6. reduce

The reduce operator is somewhat similar to the scan operator in that the reduce operator applies a function to the first element. The result is then filled in as an argument to the second element’s application function. And so on, until the final result is emitted after iterating through all the elements.

Example:

    let disposeBag = DisposeBag()

    Observable.of(10, 20, 30)
        .reduce(0, accumulator: +)
        .subscribe(onNext: { print($0Disposed (by: disposeBag) // Result: 60Copy the code

7.toArray

The toArray operator converts a sequence into an array, sends it as a single event, and then terminates.

Example:

    let disposeBag = DisposeBag()
 
    Observable.of(1, 2, 3)
        .toArray()
        .subscribe(onNext: { print($0Disposed (by: disposeBag) // result: [1,2,3]Copy the code

Combinatorial operator

1. merge

The merge operator merges Observables into one Observable. By using the Merge operator, multiple Observables can be merged into one Observables. When an Observable emits an element, it emits that element.

Observable
onError
Observable
onError

It is worth noting that the sequence elements to be merged here must be of the same type.

Example:

    let disposeBag = DisposeBag()
        
    let Henry = PublishSubject<Int>()
    let Jeannie = PublishSubject<Int>()
        
    Observable.of(Henry, Jeannie)
        .merge()
        .subscribe(onNext: { print($0) }) .disposed(by: disposeBag) Henry.onNext(1) Henry.onNext(2) Jeannie.onNext(100) Henry.onNext(3) Henry.onNext(4) Jeannie.onNext(1000) // Result: 1 2 100 3 4 1000Copy the code

2. startWith

The startWith operator inserts event elements into the Observable header. The pre-inserted event elements are emitted before the emitted event elements of an Observable.

Observable
Observable

Example:

    let disposeBag = DisposeBag()
        
    Observable.of("1"."2")
        .startWith("A")
        .startWith("B")
        .startWith("a"."b")
        .subscribe(onNext: { print($0Disposed (by: disposeBag) // Result: A B Ba 1 2Copy the code

3. zip

The ZIP operator compresses elements from multiple Observables, and it waits until each Observable element event corresponds to it before merging, and then emits the resulting element for each combination.

zip
Observables
Observable
Observables
Observables
Observables
Observables

Example:

    let disposeBag = DisposeBag()
    let Henry = PublishSubject<String>()
    let Jeannie = PublishSubject<String>()
        
    Observable.zip(Henry, Jeannie) { $0 + The $1 }
        .subscribe(onNext: { print($0) })
        .disposed(by: disposeBag)
    
    Henry.onNext("1")
    Jeannie.onNext("A")
    Henry.onNext("2")
    Jeannie.onNext("B")
    Jeannie.onNext("C")
    Henry.onNext("3")
    Henry.onNext("4") // Result: 1A 2B 3CCopy the code

The ZIP operator is often used to consolidate network requests. For example, if we want to send two requests at the same time, only after both requests are successful, we can combine the results of the two requests and continue processing. This can be done with zip.

4. combineLatest

The combineLatest operator also merges multiple Observables sequence elements. But different from ZIP, it merges the latest event element of each Observable sequence and sends the combined element whenever a new event is emitted by any Observable. (That is, if these Observables have ever emitted elements).

Example:

    let disposeBag = DisposeBag()
    let Henry = PublishSubject<String>()
    let Jeannie = PublishSubject<String>()
    
    Observable.combineLatest(Henry, Jeannie) { $0 + The $1 }
        .subscribe(onNext: { print($0) })
        .disposed(by: disposeBag)
    
    Henry.onNext("1")
    Jeannie.onNext("A")
    Henry.onNext("2")
    Jeannie.onNext("B")
    Jeannie.onNext("C")
    Henry.onNext("3")
    Henry.onNext("4") // Results: 1A 2A 2B 2C 3C 4CCopy the code

5. concat

The concat operator concatenates Observables in sequence, and the next Observable will not be sent until a completed event is emitted from the previous Observable.

Example:

    let disposeBag = DisposeBag()
    let Henry = BehaviorSubject(value: 1)
    let Jeannie = BehaviorSubject(value: 2)
    let Henry_Subject = BehaviorSubject(value: Henry)
        
    Henry_Subject.asObservable()
        .concat()
        .subscribe(onNext: { print($0) }) .disposed(by: disposeBag) Henry.onNext(3) Henry_Subject.onNext(Jeannie) Jeannie.onNext(5) Jeannie.onNext(6) Henry.onCompleted() Jeanny.onnext (7) // Result: 1 3 6 7Copy the code

The concat operator is similar to the concatMap operator in that it does not send the next Observable until a completed event is emitted from the previous Observable.

6. withLatestFrom

The withLatestFrom operator combines the two Observables’ latest elements in a function that sends the combined element out when the first Observable emits an element.

Example:

    let disposeBag = DisposeBag()
    let firstSubject = PublishSubject<String>()
    let secondSubject = PublishSubject<String>()

    firstSubject
         .withLatestFrom(secondSubject) {
              (first, second) in
              return first + second
         }
         .subscribe(onNext: { print($0) })
         .disposed(by: disposeBag)

    firstSubject.onNext("A ️")
    secondSubject.onNext("1")
    firstSubject.onNext("B"// Result: B1Copy the code

Filter condition operator

1. filter

The filter operator is used to filter out undesirable events, emitting only Observable elements that pass detection.

Example:

    let disposeBag = DisposeBag()

    Observable.of(11, 22, 3, 8, 2, 1)
          .filter { $0 > 10 }
          .subscribe(onNext: { print($0Disposed (by: disposeBag) // Result: 11 22Copy the code

2. take

The take operator emits only n elements from the Observable, automatically sending a.completed event when that number is satisfied.

Example:

    let disposeBag = DisposeBag()

    Observable.of(1, 2, 3, 4, 5, 6)
        .take(3)
        .subscribe(onNext: { print($0Disposed (by: disposeBag) // Result: 1 2 3Copy the code

3. takeLast

The takeLast operator is similar to the take operator in that it sends only the last n elements of the Observable sequence and ignores the preceding elements.

Example:

let disposeBag = DisposeBag()

    Observable.of(1, 2, 3, 4, 5, 6)
        .takeLast(3)
        .subscribe(onNext: { print($0Disposed (by: disposeBag) // Result: 4 5 6Copy the code

4. takeWhile

The takeWhile operator determines in turn whether each value of the Observable sequence satisfies a given condition. It completes automatically when the first value that does not meet the condition appears.

Example:

   let disposeBag = DisposeBag()
 
   Observable.of(2, 3, 4, 5, 6)
       .takeWhile { $0 < 4 }
       .subscribe(onNext: { print($0Disposed (by: disposeBag) // Result: 2 3Copy the code

5. takeUntil

The takeUntil operator ignores elements emitted after the second Observable generates the event. That is, the takeUntil operator looks at the source Observable, which also looks at the second Observable. Once the second Observable emits an element or a termination event, the source Observable automatically completes and stops sending events.

Example:

    let disposeBag = DisposeBag()
        
    let Henry = PublishSubject<String>()
    let Jeannie = PublishSubject<String>()
        
    Henry
        .takeUntil(Jeannie)
        .subscribe { print($0) }
        .disposed(by: disposeBag)
        
    Henry.onNext("Good")
    Henry.onNext("Lucky")
    Jeannie.onNext("Bug")
    Henry.onNext("Tnanks")
    Henry.onNext("a lot"// Result: Next (Good) Next (Lucky) completedCopy the code

6. skip

The skip operator skips the first n element events emitted by the source Observable sequence.

Example:

    let disposeBag = DisposeBag()
 
    Observable.of(1, 2, 3, 4)
        .skip(2)
        .subscribe(onNext: { print($0Disposed (by: disposeBag) // Result: 3 4Copy the code

7. skipWhile

The skipWhile operator lets you ignore the first few events that satisfy the condition in the source Observable.

Example:

    let disposeBag = DisposeBag()
 
    Observable.of(2, 3, 4, 5, 6)
        .skipWhile { $0 < 5 }
        .subscribe(onNext: { print($0Disposed (by: disposeBag) // Result: 5 6Copy the code

8. skipUntil

In addition to subscribing to the source Observable, skipUntil can also be used to monitor another Observable. The skipUntil operator skips the first elements of an Observable until another Observable emits an element.

Example:

    let disposeBag = DisposeBag()
        
    let Henry = PublishSubject<Int>()
    let Jeannie = PublishSubject<Int>()
        
    Henry
        .skipUntil(Jeannie)
        .subscribe(onNext: { print($0) }) .disposed(by: OnNext (0) henry.onnext (3) henry.onnext (4) // Still receiving messages Jeanny.onnext (0) Henry. OnNext (5) // Result: 3 4 5Copy the code

9. elementAt

The elementAt operator emits only the NTH element of an Observable, which handles only element events in a given location

Example:

    let disposeBag = DisposeBag()

    Observable.of(1, 2, 3, 4)
        .elementAt(2)
        .subscribe(onNext: { print($0Disposed (by: disposeBag) // Result: 3Copy the code

10. distinctUntilChanged

The distinctUntilChanged operator is used to filter out consecutive duplicate events. If the latter element is the same as the previous one, the element will not be emitted. If the latter element is not the same as the previous one, the element will be emitted.

Example:

    let disposeBag = DisposeBag()
 
    Observable.of(1, 2, 1, 1, 1, 3)
        .distinctUntilChanged()
        .subscribe(onNext: { print($0Disposed (by: disposeBag) // Result 1 2 1 3Copy the code

11.amb

The amB operator takes the first Observable that emitted an element or generated an event in multiple Observables. The event can be a Next, error, or completed event, and emits only the Observable element event. Ignore the other Observables.

Example:

    let disposeBag = DisposeBag()
 
    let subject1 = PublishSubject<Int>()
    let subject2 = PublishSubject<Int>()
    let subject3 = PublishSubject<Int>()
 
    subject1
        .amb(subject2)
        .amb(subject3)
        .subscribe(onNext: { print($0) })
        .disposed(by: disposeBag)
 
    subject2.onNext(1)
    subject1.onNext(20)
    subject2.onNext(2)
    subject1.onNext(40)
    subject3.onNext(0)
    subject2.onNext(3)
    subject1.onNext(60)
    subject3.onNext(0)
    subject3.onNext(0)
    
    //结果:
    1
    2
    3
Copy the code

conclusion

This is the summary of the higher order functions of RxSwift. From these simple examples, these operators can be very helpful when working with sequences and are simple to use. Learn RxSwift well and go anywhere.

Thanks for RxSwift Chinese documentation