# Swift `for-in`循环

> 原文： [https://www.programiz.com/swift-programming/for-in-loop](https://www.programiz.com/swift-programming/for-in-loop)

#### 在本文中，您将了解`for-in`循环，其用例和变体。

`For-in`循环用于运行一组任务一定次数。 这些循环遍历任何序列，例如数组中的项目，范围或字符串中的字符。

我们还使用`for-in`循环在固定的时间内执行一些重复的过程。

* * *

## 为什么需要`for in`循环？

想象有人告诉您编写一个输出`"Hello, World!"`的程序！ 在屏幕上。 您的解决方案将是：

```swift
print("Hello, World!")
```

如果他们改变主意并告诉您编写一个在屏幕上显示五次`"Hello, World!"`的程序，该怎么办？ 如果没有循环知识，您的解决方案可能是：

```swift
print("Hello, World!")
print("Hello, World!")
print("Hello, World!")
print("Hello, World!")
print("Hello, World!")
```

嗯，完成五次相似的代码来完成相同的工作看起来很耗时。 如果是这样，如果有人要求您编写一个在屏幕上输出数百甚至上百万次`"Hello, World!"`的程序，您将怎么办？ 

一种幼稚的解决方案是将`print`语句写入给定的次数。 听起来很疯狂吧？ 但是，使用`for-in`循环和以下几行代码可以找到更好的解决方案：

```swift
for i in 1...100 {
	//outputs Hello world for 100 times in the screen
	print("Hello, World!")
} 
```

不用担心语法，我们将在下面进行探讨。

* * *

## `for in`循环语法

您可以在 Swift 中创建一个`for in`循环，如下所示：

```swift
for <value> in <range> {
	<some work here>
}

```

上面的循环遍历一个范围，我们可以在`<value>`变量中访问从该范围返回的每个元素。 如果您不了解范围，则可以查看以下文章： [Swift 范围](/swift-programming/ranges "Swift ranges")。

* * *

## 它是如何工作的？

*   被迭代的序列是`<range>`。
*   `<value>`设置为该范围内的第一个数字，并且执行**循环内部的语句**。
*   执行该语句后，`<value>`被更新为`<range>`语句包含的第二个值，`<some work here>`再次被执行。
*   该过程一直持续到到达范围的终点并停止循环。

### 示例 1：`for-in`循环在 Swift 中的工作方式

```swift
for i in 1...3 {
	print("Hello world!. Value is \(i)")
} 
```

运行该程序时，输出为：

```swift
Hello world!. Value is 1
Hello world!. Value is 2
Hello world!. Value is 3 
```

在上面的程序中，要迭代的序列的范围是 1 到 3。

`i`的值设置为范围（1）中的第一个数字，并在每次迭代时更新为范围的下一个数字。 此过程一直持续到到达范围（3）的末尾。

`For-in`循环执行步骤

| 迭代 | 从范围（`i`）返回的值 | 输出 |
| --- | --- | --- |
| 1 | 1 | `Hello world!. Value is 1` |
| 2 | 2 | `Hello world!. Value is 2` |
| 3 | 3 | `Hello world!. Value is 3` |

* * *

## 在`for-in`循环中舍弃范围值

如果循环内没有使用范围值，则可以在 Swift 中使用`_`（下划线）将其丢弃，如下所示：

```swift
for _ in <range> {
	<some work here>
}

```

### 示例 2：在`for-in`循环中丢弃范围值

```swift
// This example neglects value and uses half open range operator
for _ in 1..<3 {
	print("Hello world!")
} 
```

运行该程序时，输出为：

```swift
Hello world!
Hello world! 
```

在上面的程序中，由于使用了[半开范围运算符](/swift-programming/ranges#half-open-range-operator "Swift half-open range operator")（`..<`），该序列的迭代范围是 1 到 2，但不包括下界（1）上限（3）。

`_`忽略范围（1）中的值，并执行打印语句。 再次调用`print`语句进行下一次迭代，并且过程结束，因为 2 是该范围内的最后一个值。

没有范围值的`for-in`循环执行步骤

| 迭代 | 范围返回的值 | 输出 |
| --- | --- | --- |
| 1 | 舍弃 | **`Hello world!`** |
| 2 | 舍弃 | **`Hello world!`** |

* * *

## `for-in`循环，使用步幅固定的间隔

如果要使循环在每次迭代中以某个固定值（而不是范围）递增，则必须使用[`stride`](https://developer.apple.com/documentation/swift/1641347-stride)方法。

### 示例 3：使用步幅的`for-in`循环

```swift
let interval = 2
for i in stride(from: 1, to: 10, by: interval) {
	print(i)
} 
```

运行该程序时，输出为：

```swift
1
3
5
7
9 
```

在上述程序中，`stride`函数返回数字序列：1、3、5、7、9。

将`i`的值设置为序列（1）的第一个数字，并执行循环内的`print`语句，该语句在控制台中输出“1”。

执行该语句后，`i`的值将更新为另一个值（3），并再次调用`print`语句。 该过程一直持续到访问序列中的所有元素为止。

使用步长的`for-in`循环执行步骤

| 值 | 条件（`i < end`） | `i`（输出） |
| --- | --- | --- |
| 1 | `1 < 10`（是） | 1 |
| `1 + 2 = 3` | `3 < 10`（是） | 3 |
| `1 + 2 * 2 = 5` | `5 < 10`（是） | 5 |
| `1 + 3 * 2 = 7` | `7 < 10`（是） | 7 |
| `1 + 4 * 2 = 9` | `9 < 10`（是） | 9 |
| `1 + 5 * 2 = 11` | `11 < 10`（否） | 停止 |

* * *

## 如何使用`for-in`循环访问集合的元素？

假设您有一个字符串数组，如下所示。 如果您不了解数组，可以将数组视为可以存储多个值的单个容器。 有关更多详细说明，请参见 [Swift 数组](/swift-programming/arrays "Swift Arrays")。

```swift
let programmingLanguages = ["Swift", "Java", "Go","JavaScript","Kotlin","Python"]
```

如果有人告诉您打印所有编程语言怎么办？

一种方法是使用索引作为`programmingLanguages[0], programmingLanguages[1]` ...来访问这些元素，依此类推，直到获得所有元素。 但这太繁琐了。

这是抢救循环。 您可以使用`for in`循环进行迭代：

### 示例 4：使用`for-in`循环访问数组（集合）的元素

```swift
let programmingLanguages = ["Swift", "Java", "Go", "JavaScript", "Kotlin", "Python"]
for language in programmingLanguages {
      print(language)
} 
```

运行该程序时，输出为：

```swift
Swift
Java
Go
JavaScript
Kotlin
Python 
```

在上面的程序中，要迭代的序列是一个字符串数组。

`language`的值设置为数组的第一个元素，并执行循环内的`print`语句，该语句在控制台中输出`Swift`。

执行该语句后，将使用数组的下一个元素更新`language`，并再次调用`print`语句。 这个过程一直持续到访问数组的最后一个元素为止。

* * *

### 示例 5：使用 for-in 循环访问字符串（集合）的元素

由于在 Swift 中[字符串](/swift-programming/characters-strings "Swift strings")也是集合，因此您可以使用`for`循环访问字符串中的每个字符。

```swift
for value in "I♥Swift!" {
	print(value)
} 
```

运行该程序时，输出为：

```swift
I
♥
S
w
i
f
t
! 
```

* * *

### 如何使用`for-in`循环访问集合的索引？

如果要访问数组的索引（数组中元素的位置，即 0、1、2），则需要使用`enumerated`方法：

#### 示例 6：使用`for-in`循环访问数组的索引

```swift
let programmingLanguages = ["Swift", "Java", "Go", "JavaScript", "Kotlin", "Python"]
for (index, language) in programmingLanguages.enumerated() {
      print("\(index):\(language)")
} 
```

运行该程序时，输出为：

```swift
0:Swift
1:Java
2:Go
3:JavaScript
4:Kotlin
5:Python 
```

在这里，枚举方法返回数组（`Int`）和值（`String`）组成的元组（`Int`，`String`）。 例如：`(0, Swift)`，`(1, Java)`...

使用`for-in`循环，可以在元组中一对一地访问这些项目。 如果您不了解元组，则可以简单地将其视为可以容纳不同类型值的容器。 有关更多详细说明，请参见 *Swift 元组*。

* * *

## 如何在`for-in`循环中使用`where`子句过滤元素？

您也可以使用`for-in`循环和`where`子句过滤内容：

```swift
for value in "I♥Swift!" where value != "!" {
	print(value) //removes exclamation sign
} 
```

运行该程序时，输出为：

```swift
I
♥
S
w
i
f
t 
```

在上面的程序中，要迭代的序列是字符串（字符集合）。

`value`设置为字符串的第一个字符，并使用`where`条件进行检查。 如果条件返回`true`，则执行循环内的块（打印语句），并在控制台中输出`"I"`。

执行该语句后，`value`更新为字符串的下一个字符，并再次检查条件。 如果条件返回`false`，则不执行该块，并且`value`更新为下一个字符。

此过程一直持续到访问字符串的最后一个字符为止。

带有过滤的`for-in`循环执行步骤

| 迭代 | 值 | `value != "!"` | 输出 |
| --- | --- | --- | --- |
| 1 | `I` | `true` | `I` |
| 2 | `♥` | `true` | `♥` |
| 3 | `S` | `true` | `S` |
| 4 | `w` | `true` | `w` |
| 5 | `i` | `true` | `i` |
| 6 | `f` | `true` | `f` |
| 7 | `t` | `true` | `t` |
| 8 | `!` | `false` | |