scan运算

/**
Applies an accumulator function over an
observable sequence and returns each
intermediate result. The specified seed value
is used as the initial accumulator value.
For aggregation behavior with no
intermediate results, see 'reduce'

see also: 'http://reactivex.io/documentation/operators/scan.html'
*/

图片描述如下:

scan运算_第1张图片
scan
extension ObservableType {
    public func scan(seed: A, accumulator: (A, E) throws -> A)-> Observable {
        return Scan(source: self.asObservable(), seed: seed, accumulator: accumulator)
    }
}


class Scan: Producer {
    typealias Accumulator = (Accumulator, Element) throws -> Accumulate

    private let _source: Observable
    private let _seed: Accumulate
    private let _accumulator: Accumulator

    init(source: Observable, seed: Accumulate, accumulator: Accumulator) {
        _source = source
        _seed = seed
        _accumulator = accumulator
    }

    override func run(observer: O)->Disposable {
        let sink = ScanSink(parent: self, observer: observer)
        sink.disposable = _source.subscribe(sink)
        return sink
    }
}

class ScanSink: Sink<)>, ObserverType {
    typealias Parent = Scan
    typealias E = ElementType

    private let _parent: Parent
    private var _accumulate: Accumulate

    init(parent: Parent, observer: O) {
        _parent = parent
        _accumulate = parent._seed
        super.init(observer: observer)
    }

    func on(event: Event) {
        switch event {
        case .Next(let element):
            do {
                _accumulate = try _parent._accumulator(_accumulate, element)
                forwardOn(.Next(_accumulate))
            }catch let error {
                forwardOn(.Error(error))
                dispose()
            }
        case .Error(let error):
            forwardOn(.Error(error))
            dispose()
        case .Completed:
            forwardOn(.Completed)
            dispose()
        }
    }
}

你可能感兴趣的:(scan运算)