Tunko Development Diary

RxSwift) Transforming Operater (scan, buffer, window, groupBy) 본문

Development/RxSwift

RxSwift) Transforming Operater (scan, buffer, window, groupBy)

Tunko 2022. 6. 3. 01:35

scan

scan 연산자는 두개의 파라미터를 받아서 변경후 원본 옵저버블로 들어온 이벤트를 가지고 옵저버블을 방출합니다. 첫번째 인자는 초기 값입니다. 두번째 인자는 accumulator : 클로저를 받아 초기값을 대상으로 연산후 옵저버블을 리턴합니다.

이때 연산된 결과는 초기값에 세팅되어 다음 연산에 활용됩니다.

let disposeBag = DisposeBag()
Observable.range(start: 1, count: 10)
    .scan(0, accumulator: {
        print("$0 : \\($0)")
        print("$1 : \\($1)")
        return $0 + $1
    })
    .subscribe{ print($0) }
    .disposed(by: disposeBag)

출력

$0 : 0
$1 : 1
next(1)
$0 : 1
$1 : 2
next(3)
$0 : 3
$1 : 3
next(6)
$0 : 6
$1 : 4
next(10)
$0 : 10
$1 : 5
next(15)
$0 : 15
$1 : 6
next(21)
$0 : 21
$1 : 7
next(28)
$0 : 28
$1 : 8
next(36)
$0 : 36
$1 : 9
next(45)
$0 : 45
$1 : 10
next(55)
completed

buffer

let disposeBag = DisposeBag() 
Observable<Int>.interval(.seconds(1), scheduler: MainScheduler.instance)
    .buffer(timeSpan: .seconds(5), count: 3, scheduler: MainScheduler.instance)
    .take(5)
    .subscribe{ print($0)}
    .disposed(by: disposeBag)

출력

next([0, 1, 2])
next([3, 4, 5])
next([6, 7, 8])
next([9, 10, 11])
next([12, 13, 14])
completed

buffer는 첫번째 인자 timeSpan 시간동안 옵저버블이 방출하는것을 수집하고 한번에 배열로 방출합니다. 1번쨰 인자는 이벤트를 수집할 시간입니다. 2번째 인자는 최대 수집 숫자 입니다. 3번쨰 인자는 스케쥴러입니다.

window

let disposeBag = DisposeBag()
Observable<Int>.interval(.seconds(1), scheduler: MainScheduler.instance)
    .window(timeSpan: .seconds(2), count: 10, scheduler: MainScheduler.instance)
    .take(5)
    .subscribe{ print($0)
        if let innerObservable = $0.element {
            innerObservable.subscribe { print("innerObservable element : \\($0)") }
        }
    }
    .disposed(by: disposeBag)

출력

next(RxSwift.AddRef<Swift.Int>)
innerObservable element : next(0)
innerObservable element : completed
next(RxSwift.AddRef<Swift.Int>)
innerObservable element : next(1)
innerObservable element : next(2)
innerObservable element : next(3)
innerObservable element : completed
next(RxSwift.AddRef<Swift.Int>)
innerObservable element : next(4)
innerObservable element : next(5)
innerObservable element : completed
next(RxSwift.AddRef<Swift.Int>)
innerObservable element : next(6)
innerObservable element : next(7)
innerObservable element : completed
next(RxSwift.AddRef<Swift.Int>)
completed
innerObservable element : next(8)
innerObservable element : next(9)
innerObservable element : completed

window 연산자는 버퍼연산자처럼 타임스탬프동안 수집된것을 작은 옵저버블로 방출합니다. 옵저버블 안에서 방출되는 옵저버블을 inner Observable 이라고 합니다. inner Observable은 지정된 최대 수만큼 방출하거나 시간이 지나면 종료됩니다.

groupUp

옵저버블이 방출하는 요소를 원하는 기준으로 방출합니다. 파라미터로 클로저를 받고 키를 받습니다. 연산자를 호출하면 그룹으로 묶여서 개별 옵저버블로 방출됩니다.

let disposeBag = DisposeBag()
let emo = ["🍎🍎🍎🍎", "🍊🍊🍊", "🥝🥝🥝", "🍉🍉", "🍐🍐"]

Observable.from(emo)
    .groupBy { $0.count }
    .subscribe(onNext: { groupObservable in
        print("groupBy기준 값 : \\(groupObservable.key)")
        groupObservable.subscribe{ print($0) }
    })
    .disposed(by: disposeBag)
groupBy기준 값 : 4
next(🍎🍎🍎🍎)
groupBy기준 값 : 3
next(🍊🍊🍊)
next(🥝🥝🥝)
groupBy기준 값 : 2
next(🍉🍉)
next(🍐🍐)
completed 
completed
completed

completed 가 3개인것을 확인 할 수 있습니다. 3개의 그룹으로 나뉘어 그룹된 옵저버블이 subscribe 이후 완료 된것을 확인할 수 있습니다.

다음엔 짝수 홀수로 나누어 보겠습니다.

Observable.range(start: 1, count: 10)
    .groupBy{ $0.isMultiple(of: 2) }
    .flatMap { $0.toArray() }
    .subscribe { print($0) }
    .disposed(by: disposeBag)

출력

next([2, 4, 6, 8, 10])
next([1, 3, 5, 7, 9])
completed
반응형
Comments