RxSwift

RxSwift - Transforming Operator

GREEN.1229 2021. 11. 10. 20:00

안녕하세요. 그린입니다🟢

이번 포스팅에서는 이전 Filtering Operator에 이어 Transforming Operator에 대해 학습해보겠습니다💁🏻

 

Transforming Operator?

변환해주는 오퍼레이터!

어떤것을 변환해줄까요?

옵저버블로 부터 방출된 값들을 다른 형태나 변형된 값으로 변화를 주고 방출하는 오퍼레이터입니다🤙🏻

 

그럼 바로 아래에서 여러가지 Transforming Operator들에 대해 살펴보겠습니다🙋🏻

 

toArray

요런 형태를 띕니다.

요소들을 하나의 어레이로 묶어주는 오퍼레이터인게 딱 보이죠?

그럼 코드로 어떻게 사용되는지 보겠습니다.

let disposeBag = DisposeBag()

Observable.of(1, 2, 3, 4, 5, 6)
  .toArray()
  .subscribe(onNext: {
    print($0)
  })
  .disposed(by: disposeBag)

// [1, 2, 3, 4, 5, 6]

이렇게 정말 간단하게 모두 하나의 어레이로 묶어 방출됩니다.

 

map

방출되는 값에 어떤 변형을 주어 방출하는 오퍼레이터입니다.

1, 2, 3이 들어와서 10을 곱해준 값을 방출되는 형식처럼 값의 변형을 일으켜줍니다.

이것도 코드로 보시죠!

let disposeBag = DisposeBag()

Observable.of(1, 2, 3, 4, 5, 6)
  .map{
    $0 * 10
  }
  .subscribe(onNext: {
    print($0)
  })
  .disposed(by: disposeBag)

// 10
// 20
// 30
// 40
// 50
// 60

이렇게 10씩 곱해주는 map 오퍼레이터를 통해 값을 방출합니다.

 

enumerated

여러 요소가 담긴 옵저버블에서 요소마다 접근해 인덱스와 값을 가지고 판단해줍니다.

위의 코드를 조금 변형해보죠!

let disposeBag = DisposeBag()

Observable.of(1, 2, 3, 4, 5, 6)
  .enumerated()
  .map{ index, num in
    index > 3 ? num : num * 10
  }
  .subscribe(onNext: {
    print($0)
  })
  .disposed(by: disposeBag)

// 1
// 2
// 3
// 4
// 50
// 60

이렇게 enumerated()를 통해 인덱스와 값을 가져와서 인덱스가 4번째 전까지는 값을 그대로 방출하고 이후는 10을 곱해 값을 방출하는걸 볼 수 있습니다👍

크.. 참 유용하네요🙌

 

flatmap

마블 다이어그램을 보면 어떤 값에 대해 어떻게 형태를 바꿔 방출하라는 조건을 주고 그것에 맞게 변형하여 방출합니다.

조금 난해하게 느껴지는 부분인데 흠.. 코드와 설명으로 한번 이해를 해보겠습니다!

우선 map과 어떤차이가 있을까요?

map은 이벤트의 값을 바꾸는거지만

flatMap은 이벤트를 다른 옵저버블로 바꿉니다.

그래서 map은 값을 flatMap은 옵저버블을 리턴하게 되는것이구요.

아 너무 어렵다 ㅠㅠ 코드로 보죠!

let observableOfInt = Observable.of(1, 2, 3)
let observableOfString = Observable.of("GREEN", "RED")	

observableOfInt
  .flatMap { (num) -> Observable<String> in
    print("Emit: \(num)")
    return observableOfString
  }
  .subscribeNext {
    print("Emit: \($0)")
}

// Emit: 1
// Emit: GREEN
// Emint: RED
// Emit: 2
// Emit: GREEN
// Emint: RED
// Emit: 3
// Emit: GREEN
// Emint: RED

1, 2, 3 Int를 가진 옵저버블과 GREEN, RED String을 가진 두 옵저버블이 있습니다.

숫자 옵저버블에 flatMap을해 문자열 옵저버블을 반환하도록 시그니쳐를 줍니다.

그리고 방출되는 값을 프린트해보면 지정해준 문자열 옵저버블이 방출되게 됩니다.

그럼 도대체 언제 쓰일 수 있을까요?

비동기적인 처리를 할때 많이 쓰일 수 있습니다.

 

flatMapLatest

flatMap과 그림을 보면 알 수 있듯이 비슷합니다.

대신 중간에 연속으로 다 방출되기전에 값이 둘이상 emit되면

마지막 이벤트만 변형되어 방출되고 그전것은 끊기게 됩니다.

즉 기존 옵저버블이 동작하고있는 도중에 새로운 옵저버블이 전달되면 기존것은 끊기게 됩니다!

그럼 이 오퍼레이터는 주로 어떨때 사용될까요?

네트워크 소통에서 많이 사용됩니다.

예를들어 검색어 자동완성같이 G만 쳤을때 나오는것과 GR을 쳤을때 나오는것이 다르듯 사용자가 마지막에 친 문자열에 대해서

자동완성을 시켜주는것과 같은 기능을 구현할 수 있습니다👍

 

flatMapFirst

그림을 찾을수 없어서 이렇게 그려봤습니다..ㅎㅎ

뭐 flatMapLatest와 비슷해요.

다만 첫번째 옵저버블이 동작하고 있을때 중간에 들어오는것을 무시해줍니다.

즉 기준점이 다르다고 보면 됩니다!

중간에 값이 에밋되어도 처음 사항을 일단 유지시켜야되는 동작들에 사용될것 같네요🙋🏻

 

마무리

이번에는 값의 변화를 주는 Transforming Operator을 알아봤습니다..!

으.. 머리가 복잡해지네요 점점 오퍼레이터가 많아질때마다?ㅎㅎ

그래도 flatMap을 사실상 많이 사용되는데 알아가는 좋은 기회가 되었어요👍

 

[참고자료]

http://reactivex.io/documentation/operators/distinct.html

 

ReactiveX - Distinct operator

In RxJS, the distinct operator has two optional parameters: a function that accepts an item emitted by the source Observable and returns a key which will be used instead of the item itself when comparing two items for distinctness a function that accepts t

reactivex.io

https://github.com/fimuxd/RxSwift/blob/master/Lectures/07_Transforming%20Operators/CH7_TransformingOperators.md

 

GitHub - fimuxd/RxSwift: RxSwift를 스터디하는 공간

RxSwift를 스터디하는 공간. Contribute to fimuxd/RxSwift development by creating an account on GitHub.

github.com

http://minsone.github.io/programming/reactive-swift-flatmap-flatmapfirst-flatmaplatest

 

[ReactiveX][RxSwift]flatMap, flatMapFirst, flatMapLatest

flatMap Rx에서 Observable에서 발행한 아이템을 다른 Observable로 만들며, 만들어진 Observable에서 아이템을 발행합니다. RxSwift에서 제공하는 예제를 살펴보면 좀 더 쉽게 이해할 수 있습니다. let sequenceIn

minsone.github.io