Swift 数组 运行 共 x 项

Swift Array Running Total to x item

Swift 有一个很棒的函数 .reduce 可以为整个数组提供 运行 总数:

let array = [1, 2, 3, 4, 5]
let addResult = array.reduce(0) { [=12=] +  }
// addResult is 15

let multiplyResult = array.reduce(1) { [=12=] *  }
// multiplyResult is 120

但是有没有一种简单的方法可以将此用于 运行 总数,只达到特定元素?例如,对于 [1, 2, 3, 4, 5] 的数组,是否有一种方法可以使用 .reduce 函数来 return 总共 运行 仅第 3 个项目 (1+ 2+3=6)?

(我知道我总是可以做一个循环,只是想通过 swift 学习所有的可能性)

reduce()调用的闭包没有关于 当前索引。 理论上可以创建一个闭包 使用捕获的变量 "remember" 它被调用的频率:

func addFirst(var count : Int) -> (Int, Int) -> Int {
    return {
        count-- > 0 ? [=10=] +  : [=10=]
    }
}

let array = [1, 2, 3, 4, 5]
let sumOfFirstThreeItems = array.reduce(0, addFirst(3) )

但这仍然会 运行 覆盖整个数组,而不仅仅是 前 3 个元素。没办法"stop"进程

更简单的方法是对数组切片进行操作:

let array = [1, 2, 3, 4, 5]
let sumOfFirstThreeItems = array[0 ..< 3].reduce(0) { [=11=] +  }

切片是一种类似 Array 的类型,表示任何的子序列 ArrayContiguousArray 或其他 Slice

除了使用数组的 reduce 方法,如@MartinR 的回答,还可以使用全局 reduce 函数和 enumerate

enumerate函数returns一个元组序列,其第一个元素(名为index)是元素索引,第二个(名为element)是元素值。

所以你可以用下面的代码达到同样的效果:

let sum = reduce(enumerate(array), 0) {
    [=10=] + (.index < 3 ? .element : 0)
}

此方法的优点是您可以应用更复杂的规则来排除元素 - 例如,对具有偶数索引的所有元素求和:

let sum = reduce(enumerate(array), 0) {
    [=11=] + (.index % 2 == 0 ? .element : 0)
}