본문 바로가기
iOS/RxSwift

[RxSwift] Combining Operators

by 0inn 2022. 11. 18.

지난 filtering이나 transforming operators들을 살펴보자면 , , Swift 표준 연산자들과 아주 유사했는데요 !

Combining Operators들도 유사한 것들이 많다고 합니다 . . 하하 가봅시다 ~

Prefixing and concatenating

단순해석하자면 앞에 붙이거나 연결하는 것들 ? 입니다 . . 흠

 

1. startWith(_:)

 

 

현재 위치나 네트워크 연결 상태와 같이 현재 상태가 필요한 상황이 있습니다.

이럴 때 현재 상태와 함께 초기값을 붙일 수 있습니다.

 

[코드]

 example(of: "startWith") {
     // 1
     let numbers = Observable.of(2, 3, 4)

     // 2
     let observable = numbers.startWith(1)
     observable.subscribe(onNext: {
         print($0)
     })

     /* Prints:
      1
      2
      3
      4
     */
 }

startWith(1)을 해줌으로써 1로 시작하는 sequence를 만들고 기존의 sequence를 이어붙여서 1 2 3 4가 출력된 것을 볼 수 있습니다.

 

2. Observable.concat(_:)

 

startWith는 concat 연산자의 단순 변형입니다.

startWith의 경우에는 하나의 값을 갖는 sequence를 다른 sequence의 앞에 연결한 형태인데요.

Observable.concat(_:)의 경우, 두 개의 sequence를 묶을 수 있습니다.

 

 

[코드]

 example(of: "Observable.concat") {
     // 1
     let first = Observable.of(1, 2, 3)
     let second = Observable.of(4, 5, 6)

     // 2
     let observable = Observable.concat([first, second])

     observable.subscribe(onNext: {
         print($0)
     })

     /* Prints:
      1
      2
      3
      4
      5
      6
     */
 }

말그대로 first와 second를 연결한 것으로 1 ~ 6까지 출력됩니다.

 

3. concat(_:)

 

[코드]

 example(of: "concat") {
     let germanCities = Observable.of("Berlin", "Münich", "Frankfurt")
     let spanishCities = Observable.of("Madrid", "Barcelona", "Valencia")

     let observable = germanCities.concat(spanishCities)
     observable.subscribe(onNext: { print($0) })
 }

concat(_:)은 Observable.concat(_:)와 달리 인스턴스 메서드인 점을 제외하고 똑같이 동작합니다.

이 때, 반드시 두 observable의 타입은 같아야겠죠 ? String과 Int를 합치려고 하면 에러가 발생합니다 ! !

 

4. concatMap(_:)

 

어라 . . flatMap이랑 관련있나 . .? 있습니다 !

flapMap 통과하면 Observable sequence가 구독을 위해 리턴되고, 방출된 observable들이 합쳐지게 됩니다.

concatMap은 각각의 sequence가 다음 sequence가 구독되기 전에 합쳐진다는 것을 보증합니다.

 

[코드]

 example(of: "concatMap") {
     // 1
     let sequences = ["Germany": Observable.of("Berlin", "Münich", "Frankfurt"),
                      "Spain": Observable.of("Madrid", "Barcelona", "Valencia")]

     // 2
     let observable = Observable.of("Germany", "Spain")
         .concatMap({ country in
             sequences[country] ?? .empty() })

     // 3
     _ = observable.subscribe(onNext: {
         print($0)
     })
 }
 
/*
Berlin
Münich
Frankfurt
Madrid
Barcelona
Valencia
*/

 

지금까지 sequence를 추가하고 합치는 방법에 대해 알아보았는데요  . . !

그럼 이제 결합해봅시다 ! ! !

Merging

1. combineLatest(_:_:resultSelector:)

내부 sequence들은 값을 방출할 때마다 제공한 클로저를 호출합니다.

우리는 각각의 내부 sequence들의 마지막 값을 받습니다.

 

[코드]

 example(of: "combineLast") {
     let left = PublishSubject<String>()
     let right = PublishSubject<String>()

     // 1
     let observable = Observable.combineLatest(left, right, resultSelector: { lastLeft, lastRight in
         "\(lastLeft) \(lastRight)"
     })

     let disposable = observable.subscribe(onNext: {
         print($0)
     })

     // 2
     print("> Sending a value to Left")
     left.onNext("Hello,")
     print("> Sending a value to Right")
     right.onNext("world")
     print("> Sending another value to Right")
     right.onNext("RxSwift")
     print("> Sending another value to Left")
     left.onNext("Have a good day,")

     // 3
     disposable.dispose()

     /* Prints:
      > Sending a value to Left
      > Sending a value to Right
      Hello, world
      > Sending another value to Right
      Hello, RxSwift
      > Sending another value to Left
      Have a good day, RxSwift
     */
 }

 

... 이어서 돌아오겠습니다 ...

'iOS > RxSwift' 카테고리의 다른 글

[RxSwift] Observable.create & Disposable.create  (0) 2022.11.22
[RxSwift] NotificationCenter, Notification  (0) 2022.11.21
[RxSwift] Transforming Operators  (0) 2022.11.17
[RxSwift] Filtering Operators  (0) 2022.10.12
[RxSwift] Subjects  (0) 2022.10.12