【问题标题】:Can't form Range with end < start Check range before doing for loop?在执行 for 循环之前,不能用 end < start 检查范围来形成范围?
【发布时间】:2016-05-10 15:41:01
【问题描述】:

我在 swift 代码中遇到了一个我不太理解的变化。

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)")
    }
}

有更聪明的解决方案吗?

【问题讨论】:

  • 您确定要0..&lt;arr.count 考虑基于 0 的索引吗?如果你只是迭代元素,那么使用for element in arr
  • ... 这也解决了您的问题,因为 0..&lt;0 是一个空范围,因此不会输入您的循环体。
  • ... 它基本上在 Swift 手册的第 2 页上:developer.apple.com/library/ios/documentation/Swift/Conceptual/…
  • 或者如果您必须从 1 开始,for i in 1 ..&lt; arr.count + 1 { 将执行您的循环执行的操作。
  • “现在苹果想让我改变”......我对此表示怀疑。 :)

标签: swift macos swift2.2


【解决方案1】:

如果您只想遍历集合,请使用for &lt;element&gt; in &lt;collection&gt; 语法。

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

如果您还需要在每次迭代时访问元素的索引,您可以使用enumerate()。因为索引是从零开始的,所以索引的范围是0..&lt;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..&lt;arr.count+1 的范围)。

如果这些都不能解决您的问题,那么您可以使用范围0..&lt;arr.count 来迭代数组的索引,或者作为@vacawama says,您可以使用范围1..&lt;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..&lt;0 不会因空数组而崩溃,因为0..&lt;0 只是一个空范围,1..&lt;arr.count+1 不会因空数组而崩溃,因为1..&lt;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 是步长。如果您的数组的元素少于给定的起始索引,则永远不会进入循环。

【讨论】:

  • 最后,如果您的起始值为 5,例如,for var i = 5; i &lt;= arr.count; i += 1 那么stride 就是您的答案:for i in 5.stride(through: arr.count, by: 1)
  • @vacawama 是的,另一种安全地进行自定义范围的巧妙方法。我已将其包含在我的答案中:)
  • stride(through:by:) 实际上将包含 through 值。使用stride(to:by:) 留在下方。
【解决方案2】:

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

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

【讨论】:

    【解决方案3】:

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

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

    ...虽然这似乎是一种计算数组中元素的复杂方法 (arr.count),所以我怀疑这个问题比表面上看到的要多。

    【讨论】:

      猜你喜欢
      • 2018-12-20
      • 2011-09-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-07-13
      • 2011-03-01
      相关资源
      最近更新 更多