【问题标题】:Swift Array Running Total to x itemSwift Array 运行总计到 x 项
【发布时间】:2015-03-30 19:04:24
【问题描述】:

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

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

let multiplyResult = array.reduce(1) { $0 * $1 }
// multiplyResult is 120

但是有没有一种简单的方法可以将其用于仅针对特定元素的运行总数?例如,对于 [1, 2, 3, 4, 5] 的数组,有没有办法使用 .reduce 函数只返回第 3 项 (1+2+3=6) 的运行总计?

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

【问题讨论】:

    标签: ios arrays swift reduce cumulative-sum


    【解决方案1】:

    除了使用数组的reduce 方法外,如@MartinR 的回答,还可以将全局reduce 函数与enumerate 一起使用

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

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

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

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

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

    【讨论】:

      【解决方案2】:

      reduce() 调用的闭包没有关于 当前指数。 理论上可以创建一个闭包 使用捕获的变量来“记住”它被调用的频率:

      func addFirst(var count : Int) -> (Int, Int) -> Int {
          return {
              count-- > 0 ? $0 + $1 : $0
          }
      }
      
      let array = [1, 2, 3, 4, 5]
      let sumOfFirstThreeItems = array.reduce(0, addFirst(3) )
      

      但这仍然会在整个数组上运行,而不仅仅是 前 3 个元素。没有办法“停止”这个过程。

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

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

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

      【讨论】:

      • 谢谢你,这正是我想要的
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-09
      • 1970-01-01
      • 1970-01-01
      • 2017-10-04
      • 2012-07-03
      • 2019-05-20
      相关资源
      最近更新 更多