Publishers.Scan

제네릭 구조체

이니셜라이저는 세 개의 인자를 받는다.

  • upstream : 상위에 흐르는 Publisher

  • initialResult : 초기 값.

  • nextPartialResult : 요소에 연속적으로 적용할 클로저

Publisher가 내는 요소에 연속적으로 함수를 적용하고 실행한 후, 성공적으로 실행된 함수의 반환 값을 낸다.

Swift의 reduce 함수와 동작이 비슷하지만 reduce가 최종 결과만을 반환한다면 scan은 함수가 적용된 요소와 다음 요소에 대해 함수를 적용하여 각 요소가 점진적으로 다시 발행된다.

scan 오퍼레이터와 관련이 있다.

// Publishers.Scan Publisher
Publishers.Scan(upstream: Publishers.Sequence<[Int], Never>(sequence: [1, 2, 3]), initialResult: 0) { $0 + $1 }
  .sink(receiveCompletion: { completion in
    switch completion {
    case .failure:
      print("Combine Scan Error")
    case .finished:
      print("Combine Scan Finish")
    }
  }, receiveValue: { value in
    print("Combine Scan : \(value)")
  })
  .store(in: &cancellables)

// scan Operator
Publishers.Sequence<[Int], Never>(sequence: [1, 2, 3])
  .scan(0) { $0 + $1 }
  .sink(receiveCompletion: { completion in
    switch completion {
    case .failure:
      print("Combine Scan Error")
    case .finished:
      print("Combine Scan Finish")
    }
  }, receiveValue: { value in
    print("Combine Scan : \(value)")
  })
  .store(in: &cancellables)

// Combine Scan : 1
// Combine Scan : 3
// Combine Scan : 6
// Combine Scan Finish

상위 Publisher는 1, 2, 3의 값을 차례대로 낸다. 점진적으로 이전의 값과 현재의 값을 더한 값을 반환하도록 하였고, 다음과 같이 동작한다.

  1. 1이 초기값 0과 더해져 1의 값을 낸다.

  2. 2가 이전의 값 1과 더해져 3의 값을 낸다.

  3. 3이 이전의 값 3과 더해져 6의 값을 낸다.

결과적으로 1, 3, 6의 값을 차례대로 내고 종료한다.

RxSwift

scan 오퍼레이터를 사용하여 구현할 수 있다.

Observable.from([1, 2, 3])
  .scan(0) { $0 + $1 }
  .subscribe(onNext: { value in
    print("RxSwift Scan : \(value)")
  }, onError: { _ in
    print("RxSwift Scan Error")
  }, onCompleted: {
    print("RxSwift Scan Finish")
  })
  .disposed(by: disposeBag)

// RxSwift Scan : 1
// RxSwift Scan : 3
// RxSwift Scan : 6
// RxSwift Scan Finish

ReactiveSwift

scan 오퍼레이터를 사용하여 구현할 수 있다.

SignalProducer([1, 2, 3])
  .scan(0) { $0 + $1 }
  .start { event in
    switch event {
    case let .value(value):
      print("ReactiveSwift Scan : \(value)")
    case .failed:
      print("ReactiveSwift Scan Error")
    case .completed:
      print("ReactiveSwift Scan Finish")
    default:
      break
    }
  }

// ReactiveSwift Scan : 1
// ReactiveSwift Scan : 3
// ReactiveSwift Scan : 6
// ReactiveSwift Scan Finish

참고

ReactiveX - Operators - Scan

Last updated