迭代数组并计算从负数到正数的变化(反之亦然)

Iterate Array and Count Changes from Negative to Positive (and vice versa)

我正在使用 CoreMotion 的 GyroData 来确定设备运动的 Z 方向。这 returns 我是一个双打数组。正向前进,负向后退。我现在想数一数该装置朝一个方向移动了多少次。向相反方向移动将是一个计数。

所以我试图计算数组中值从正值变为负值或从负值变为正值的次数。如果这是数组,则计数将为 3。

let array = [1, 2, 3, 4, -1, -1, -2, -3, 1, 2, 3, -1, -2]

是否可以一行完成?我觉得我完全无法用这段代码使事情复杂化:

var count = 0
var isPositive = false

for (index, value) in array.enumerated() {

  if isPositive == false {
      if value > 0 {
          isPositive = true
          count += 1
      }
   } else {
      if value < 0 
          isPositive = false
          count += 1
      }
   }
}

谢谢!!

注意:关于计算哪些对的确切逻辑可能会发生变化,因为我还不确定您要查找的是什么。它应该足够简单,可以根据需要进行适当的更改。

首先,我要澄清一下我们正在寻找什么样的过渡。我将研究从负数(小于 0)到非负数(0 和所有正数)的转换。我将使用以下扩展来简化它:

extension Integer {
    var isNonNegative: Bool { return !isNegative }
    var isNegative: Bool { return self < 0 }
}

在这种情况下,当您尝试迭代成对的序列时,zip(_:_:) 会派上用场。

let array = [1, 2, 3, 4, -1, -1, -2, -3, 1, 2, 3, -1, -2]
let pairs = zip(array, array.dropFirst(1))
print(Array(pairs))

结果是这些对:

[(1, 2), (2, 3), (3, 4), (4, -1), (-1, -1), (-1, -2), (-2, -3), (-3, 1), (1, 2), (2, 3), (3, -1), (-1, -2)]

从这里开始,只需计算第一个元素(.0)为负数,第二个元素(.1) 为阳性。像这样:

let numRisingEdges = pairs.reduce(0) { count, pair in
    if pair.0.isNegative && pair.1.isNonNegative { return count + 1 }
    else { return count }
}

print(numRisingEdges) // => 1

我不喜欢我自己之前的回答,所以这里有一个稍微不同的方法:

    let array = [1, 1, 2, 3, 4, -1, -1, -2, -3, 1, 2, 3, -1, -2]
    func sign(_ i: Int) -> Int {
        switch true {
        case i > 0: return 1
        case i < 0: return -1
        default: return 0
        }
    }
    let result = array.map{sign([=10=])}.reduce([Int]()) { arr, cur in
        var arr = arr
        if arr.count == 0 {
            arr.append(cur)
        } else if arr.last! != cur {
            arr.append(cur)
        }
        return arr
    }
    print(result.count-1) // 3

我们的想法是将 arr 维护为符号更改的暂存器。但是 first 条目不算数,因为它之前没有任何内容,因此通过从更改总数中减去 1 来打折它。