๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
IOS๐ŸŽ/RxSwift

[RxSwift] Transforming Operator (map, flatMap, scan, reduce)

by Jouureee 2022. 5. 16.

์˜ค๋Š˜์€ observable ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€๊ณตํ•˜๋Š” operator์— ๋Œ€ํ•ด ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

1) Map

Observerble์— ์˜ํ•ด ๋ฐฉ์ถœ๋˜๋Š” ์•„์ดํ…œ๋“ค์— ๋Œ€ํ•ด ๊ฐ๊ฐ ํ•จ์ˆ˜๋ฅผ ์ ์šฉํ•˜์—ฌ ๋ณ€ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

 

map์„ ์‚ฌ์šฉํ•˜๋Š” ์˜ˆ์‹œ์ž…๋‹ˆ๋‹ค.

let ob = Observable.of("1", "2", "3", "4")
ob.map { Int($0)! }
    .subscribe(onNext: { item in
        print(item)
    }).disposed(by: disposeBag)

//์ถœ๋ ฅ
//1
//2
//3
//4

stringํƒ€์ž…์˜ observable์„ map operator๋ฅผ ํ†ตํ•ด ๋ชจ๋“  item์„ Int ํƒ€์ž…์œผ๋กœ ์บ์ŠคํŒ… ํ•ด์ฃผ์—ˆ์Šต๋‹ˆ๋‹ค.

 

 

2) FlatMap

flatMap์€ map๊ณผ๋Š” ๋‹ค๋ฅด๊ฒŒ ์ŠคํŠธ๋ฆผ์—์„œ ๋ฐฉ์ถœ๋˜๋Š” ์•„์ดํ…œ๋“ค์„ ๋‹ค๋ฅธ observable๋กœ ๋งŒ๋“ญ๋‹ˆ๋‹ค. 

๊ทธ๋Ÿฌ๋ฏ€๋กœ flatMap์˜ ๋ฆฌํ„ด๊ฐ’์€ ์ƒ์„ฑ๋œ observable์ž…๋‹ˆ๋‹ค.

์˜ˆ์‹œ๋ฅผ ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

 

button.rx.tap
.flatMap { void -> Observable<[String]> in
    return fetchAllAnswers()
}.subscribe(onNext: { str in
    item.value = str
}).disposed(by: disposeBag)

func fetchAllAnswers() -> Observable<[String]> {
  let api = Observable.create { (obsever: AnyObserver<[String]>) -> Disposable in
       let answers = API.allAnswers()
        obsever.onNext(answers)
        obsever.onCompleted()
      return Disposables.create()
    }
    return api
}

๋ฒ„ํŠผ์„ ํด๋ฆญํ–ˆ์„ ๋•Œ, ๋ฐ์ดํ„ฐ๋ฅผ ๋ถˆ๋Ÿฌ์˜ค๋Š” fetchAllAnswers() ํ•จ์ˆ˜๋ฅผ ์‹คํ–‰ํ•ด ๊ฐ’์„ ๋ฐœ์ƒํ•˜๋Š” ์ฝ”๋“œ์ž…๋‹ˆ๋‹ค.

 

3) Scan

์ด์ „์— ๋ฐฉ์ถœ๋œ ์•„์ดํ…œ๊ณผ ์ƒˆ๋กœ ๋ฐฉ์ถœ๋œ ์•„์ดํ…œ์„ ๊ฒฐํ•ฉํ•ด ํ˜„์žฌ ์•„์ดํ…œ์„ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

 

์˜ˆ์‹œ ์ฝ”๋“œ์ž…๋‹ˆ๋‹ค.

Observable.of(1,2,3,4,5)
   .scan(0) { (prevValue, newValue) in
      return prevValue + newValue
   }
   .subscribe(onNext: { print($0) })
   .disposed(by: disposeBag)
// ์ถœ๋ ฅ
// 1
// 3
// 6
// 10
// 15

 

scan์˜ ํ™œ์šฉ

 

1. ๋ฒ„ํŠผ ์ƒํƒœ ๋ณ€๊ฒฝ

myButton.rx.tap
   .scan(false) { (lastState, newValue) in
      !lastState
   }
   .bind(to: requestMoreButton.rx.isSelected)
   .disposed(by: disposeBag)

 

2. ํƒ€์ด๋จธ ๊ฐ’ 1 ์ฆ๊ฐ€

myButton.rx.tap
   .scan(0) { (lastCount, newValue) in
      lastCount + 1
   }
   .subscribe(onNext: { print(“taps: \($0)”) })
   .disposed(by: disposeBag)

์ฐธ๊ณ  : https://jusung.github.io/scan/

 

4) reduce

scan๊ณผ ๋‹ฌ๋ฆฌ ๋งˆ์ง€๋ง‰์— ๋‹ค ๋”ํ•œ ๊ฐ’์„ ํ•œ๋ฒˆ๋งŒ ๋ฐฉ์ถœํ•ฉ๋‹ˆ๋‹ค.

 

์˜ˆ์‹œ 

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

'IOS๐ŸŽ > RxSwift' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€

[RxSwift] Filtering Operator (distinctUntilChanged)  (0) 2022.05.10
[RxSwift] Error Handling Operator  (0) 2022.05.10
[RxSwift] Schedular๋ž€ (subscribeOn, observeOn)  (0) 2022.04.29
[RxSwift] Signal, ControlProperty, ControlEvent ๋ž€ ?  (0) 2022.03.21
[RxSwift] Driver๋ž€ ? (feat. bind)  (0) 2022.03.21

๋Œ“๊ธ€