Swift running sum

前端 未结 7 1027
一生所求
一生所求 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条回答
  •  悲哀的现实
    2020-12-01 19:03

    The general combinator you're looking for is often called scan, and can be defined (like all higher-order functions on lists) in terms of reduce:

    extension Array {
        func scan(initial: T, _ f: (T, Element) -> T) -> [T] {
            return self.reduce([initial], combine: { (listSoFar: [T], next: Element) -> [T] in
                // because we seeded it with a non-empty
                // list, it's easy to prove inductively
                // that this unwrapping can't fail
                let lastElement = listSoFar.last!
                return listSoFar + [f(lastElement, next)]
            })
        }
    }
    

    (But I would suggest that that's not a very good implementation.)

    This is a very useful general function, and it's a shame that it's not included in the standard library.

    You can then generate your cumulative sum by specializing the starting value and operation:

    let cumSum = els.scan(0, +)
    

    And you can omit the zero-length case rather simply:

    let cumSumTail = els.scan(0, +).dropFirst()
    

提交回复
热议问题