Tunko Development Diary

RxSwift) Transforming Operator (toArray, map, compactMap) 본문

Development/RxSwift

RxSwift) Transforming Operator (toArray, map, compactMap)

Tunko 2022. 6. 2. 20:51

toArray

toArray는 옵저버블이 방출하는 모든 이벤트를 완료시점에 배열로 방출합니다.

let disposeBag = DisposeBag()
let subject = PublishSubject<Int>()
subject
    .toArray()
    .subscribe{ print($0) }
    .disposed(by: disposeBag)

subject.onNext(1)
subject.onNext(2)
subject.onNext(3)
subject.onNext(4)
subject.onNext(5)
subject.onCompleted()

출력

success([1, 2, 3, 4, 5])

옵저버블이 Completed가 되지 않으면 아무것도 방출하지 않습니다.

map

let disposeBag = DisposeBag()
let skills = ["🍎", "🍊🍎", "🍉🍊🍎"]

Observable.from(skills)
    .map { "text \\($0)" }
    .map { $0.count }
    .subscribe { print($0) }
    .disposed(by: disposeBag)

출력

next(6)
next(7)
next(8)
completed

map 함수원형

public func map<Result>(_ transform: @escaping (Element) throws -> Result)
        -> Observable<Result> {
    Map(source: self.asObservable(), transform: transform)
}

map연산자는 클로저를 받아 옵저버블을 리턴합니다.

옵저버블이 방출하는 대상으로 함수를 실행합니다. 그런 다음 실행결과를 방출하는 옵저버블을 리턴합니다.

map 연산자에선 다른 타입의 값으로 변경이 가능합니다. 위 코드처럼 String데이터를 Int형으로 내보낼수 있습니다.

compactMap

let disposeBag = DisposeBag()
let subject = PublishSubject<String?>()

subject
    .compactMap{ $0 }
    .subscribe { print($0) }
    .disposed(by: disposeBag)

Observable<Int>.interval(.milliseconds(100), scheduler: MainScheduler.instance)
    .take(5)
    .map { _ in Bool.random() ? "" : nil }
    .subscribe(onNext: { subject.onNext($0) })
    .disposed(by: disposeBag)

compactMap 연산자는 옵저버블에서 방출되는 이벤트를 꺼낸 다음 옵셔널형태로 바꾸고 원하는 변환을 실행합니다. 그리고. 최종 변환된 값이 nil이면 방출하지 않습니다.

하지만 위의 경우는 filter 연산자를 사용해도 가능합니다.

.filter { $0 != nil }

이런식으로

하지만 출력 결과는

next(Optional("🍎"))
next(Optional("🍎"))
next(Optional("🍎"))

이렇게 나타납니다. 방출된 값이 옵셔널로 변환 되기 때문에 변경을 추가해야합니다.

.filter { $0 != nil }
.map { $0! }

map연산자를 통해 방출되는 값을 언랩핑해주었습니다.

위와 같은 상황을 줄여주는게 compactMap 입니다. 방출되면서 자동으로 언랩핑을 해주기에 방출되는 값만 처리 할 수 있게 됩니다.

반응형
Comments