Swift running sum

前端 未结 7 1021
一生所求
一生所求 2020-12-01 18:25

I\'d like a function runningSum on an array of numbers a (or any ordered collection of addable things) that returns an array of the same length where each eleme

7条回答
  •  Happy的楠姐
    2020-12-01 18:59

    I thought I'd be cool to extend Sequence with a generic scan function as is suggested in the great first answer.

    Given this extension, you can get the running sum of an array like this: [1,2,3].scan(0, +)

    But you can also get other interesting things…

    • Running product: array.scan(1, *)
    • Running max: array.scan(Int.min, max)
    • Running min: array.scan(Int.max, min)

    Because the implementation is a function on Sequence and returns a Sequence, you can chain it together with other sequence functions. It is efficient, having linear running time.

    Here's the extension…

    extension Sequence {
    
        func scan(_ initialResult: Result, _ nextPartialResult: @escaping (Result, Self.Element) -> Result) -> ScanSequence {
            return ScanSequence(initialResult: initialResult, underlying: self, combine: nextPartialResult)
        }
    }
    
    struct ScanSequence: Sequence {
    
        let initialResult: Result
        let underlying: Underlying
        let combine: (Result, Underlying.Element) -> Result
    
        typealias Iterator = ScanIterator
    
        func makeIterator() -> Iterator {
            return ScanIterator(previousResult: initialResult, underlying: underlying.makeIterator(), combine: combine)
        }
    
        var underestimatedCount: Int {
            return underlying.underestimatedCount
        }
    }
    
    struct ScanIterator: IteratorProtocol {
    
        var previousResult: Result
        var underlying: Underlying
        let combine: (Result, Underlying.Element) -> Result
    
        mutating func next() -> Result? {
            guard let nextUnderlying = underlying.next() else {
                return nil
            }
    
            previousResult = combine(previousResult, nextUnderlying)
            return previousResult
        }
    }
    

提交回复
热议问题