迭代数组和计数从负数变为正数(反之亦然)

时间:2017-03-14 15:51:15

标签: arrays swift enumeration

我正在使用CoreMotion的GyroData来确定设计运动的Z方向。这将返回一系列双打。积极向前移动,负向后移动。我现在想要计算设计在一个方向上移动多少次。向相反方向移动将是一个计数。

所以我试图计算数值从正值变为负值或从数组内的负数变为正数的次数。如果这是数组,则计数为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
      }
   }
}

谢谢!

2 个答案:

答案 0 :(得分:0)

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

首先,我要澄清一下我们正在寻找什么样的过渡。我将关注从负数(小于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

答案 1 :(得分:0)

我不喜欢我之前的回答,所以这里的方法略有不同:

    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($0)}.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作为符号更改的暂存器。但是第一个条目并不算数,因为它之前没有任何内容,所以通过从总体更改计数中减去1来对其进行折扣。