一尘不染

迅速的总和

swift

我想要一个runningSum数字数组上的函数(或任何可加的事物的有序集合),该函数返回长度相同的数组,其中每个元素i是A中所有元素的总和,
直到一个includei

例子:

runningSum([1,1,1,1,1,1]) -> [1,2,3,4,5,6]
runningSum([2,2,2,2,2,2]) -> [2,4,6,8,10,12]
runningSum([1,0,1,0,1,0]) -> [1,1,2,2,3,3]
runningSum([0,1,0,1,0,1]) -> [0,1,1,2,2,3]

我可以使用for循环或其他方式执行此操作。还有更多功能选择吗?它有点像reduce,只是它会构建一个包含所有中间值的结果数组。

更通用的是具有可以接受任何序列并提供输入序列的总运行时间的函数。


阅读 204

收藏
2020-07-07

共1个答案

一尘不染

您正在寻找的通用组合器通常称为scan,可以按照以下方式进行定义(就像列表中的所有高阶函数一样)reduce

extension Array {
    func scan<T>(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)]
        })
    }
}

(但是我建议这不是一个很好的实现。)

这是一个非常有用的常规函数​​,但遗憾的是它没有包含在标准库中。

然后,您可以通过专门设置起始值和操作来生成累积和:

let cumSum = els.scan(0, +)

您可以简单地省略零长度的情况:

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