45

所以,我有一个看起来与此类似的 for 循环:

for var i = 0; i < results.count ; i += 1 {
   if (results[i] < 5) {
      results.removeAtIndex(i)
      i -= 1
   }
}

这曾经奏效。但是当我将其更改为首选的 Swift 3.0 语法时:

for var i in 0..<results.count {
   if (results[i] < 5) {
      results.removeAtIndex(i)
      i -= 1
   }
}

我得到一个数组 IOOBE 异常,因为它不会重新检查计数并继续直到原始results.count.

我该如何解决?它现在有效,但我不想在未来遇到麻烦。

4

4 回答 4

76

虽然使用的解决方案filter是一个很好的解决方案,而且它更Swift-ly,还有另一种方法,如果for-in仍然需要使用:

func removeBelow(value: Int) {
    var results = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

    for i in (0 ..< results.count).reversed() {
        if (results[i] < value) {
            results.remove(at: i)
        }
    }

    print(results)
}

removeBelow(value: 5)

结果:

[5, 6, 7, 8, 9, 10]

循环内的问题是它不会导致数组就地removeAtIndex重新索引自身,从而由于未更新而导致数组越界异常。count

通过向后遍历,可以避免越界异常。

于 2016-06-03T23:40:02.267 回答
18

你能用 afilter代替吗?

let numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
let greaterThan4 = numbers.filter{$0 >= 5}
print(greaterThan4)
于 2016-06-02T15:29:15.917 回答
13

如果您想继续使用for-loop,您可以使用以下方式枚举索引和元素enumerate

for (index, element) in results.enumerate() {
   if (element < 5) {
     results.removeAtIndex(index)
   }
}

尽管取决于您在循环中所做的事情,但该filter方法可能是一个更好的主意。

于 2016-06-02T15:33:39.197 回答
0

如果你的循环继续......

for var i in (0..<results.count) where results.indices.contains(i) { 

//if the index doesn't exist, the loop will be stopped.

if (results[i] < 5) {
        results.removeAtIndex(i) 
    }

}
于 2017-08-18T09:23:19.520 回答