无法形成范围与结束<在进行循环之前启动检查范围?

时间:2016-05-10 15:41:01

标签: swift macos swift2.2

我遇到了一些我不太了解的快速代码的变化。

var arr = []
for var i = 1; i <= arr.count; i += 1
{
    print("i want to see the i \(i)")
}

我有一个程序可以得到一个也可以为空的结果数组。这对于上面的for循环没有问题。 现在,苹果希望我将代码更改为以下内容。但是如果数组为空,这将崩溃。

var arr = []
for i in 1...arr.count
{
   print("i want to see the i \(i)")
}

在我做循环之前,我是否真的必须首先检查范围?

var arr = []
if (arr.count >= 1){
    for i in 1...arr.count
    {
        print("I want to see the i \(i)")
    }
}

有更聪明的解决方案吗?

3 个答案:

答案 0 :(得分:11)

如果您只想迭代集合,请使用for <element> in <collection>语法。

for element in arr {
    // do something with element
}

如果您还需要在每次迭代时访问元素的索引,则可以使用enumerate()。由于索引基于零,因此索引的范围为0..<arr.count

for (index, element) in arr.enumerate() {

    // do something with index & element

    // if you need the position of the element (1st, 2nd 3rd etc), then do index+1
    let position = index+1
}

您总是可以在每次迭代时向索引添加一个以访问该位置(以获得1..<arr.count+1的范围。)

如果这些都无法解决您的问题,那么您可以使用范围0..<arr.count来迭代数组的索引,或者@vacawama says,您可以使用范围1..<arr.count+1来迭代这些职位。

for index in 0..<arr.count {

    // do something with index
}

for position in 1..<arr.count+1 {

    // do something with position
}

0..<0对于空数组不会崩溃,因为0..<0只是一个空范围,而1..<arr.count+1不能为空数组崩溃,因为1..<1也是一个空范围。

另请参阅@vacawama's comment below有关使用stride安全地执行更多自定义范围的信息。例如(Swift 2语法):

let startIndex = 4
for i in startIndex.stride(to: arr.count, by: 1) {
    // i = 4, 5, 6, 7 .. arr.count-1
}

Swift 3语法:

for i in stride(from: 4, to: arr.count, by: 1) {
    // i = 4, 5, 6, 7 .. arr.count-1
}

这是startIndex是开始范围的数字,arr.count是范围将保持在下方的数字,1是步幅。如果您的数组的元素少于给定的起始索引,则永远不会输入循环。

答案 1 :(得分:3)

在这种情况下,显而易见的解决方案是:

var arr = []
for i in arr.indices {
    print("I want to see the i \(i)") // 0 ... count - 1
    print("I want to see the i \(i + 1)") // 1 ... count
}

但请仔细阅读originaluser2's answer

答案 2 :(得分:1)

这应该产生与第一个例子相同的结果,没有错误......

var arr = []
var i=1
for _ in arr
{
    print("i want to see the i \(i)")
    i += 1
}

...虽然这似乎是一种计算数组中元素的复杂方法(arr.count),所以我怀疑这个问题还有更多的东西,而不是眼睛。