---
# System prepended metadata

title: 'Day 6 - Loops, summary, and checkpoint 3'

---

# Day 6 - Loops, summary, and checkpoint 3

## How to use a for loop to repeat work

- 電腦很適合做重複性高的工作，Swift允許做一個固定次數的重複動作，或是針對一個 `array` 、 `set` 或 `dictionary` 中的每一項各做一次同種動作
- ex: 針對 `array` 中的每一項各做一次同種動作
    ```
    let platforms = ["iOS", "macOS", "tvOS", "watchOS"]

    for os in platforms {
      print("Swift works great on \(os)")
    }
    
    // Swift works great on iOS
    Swift works great on macOS
    Swift works great on tvOS
    Swift works great on watchOS
    ```
    - loop body
        ```
        print("Swift works great on \(os)")
        ```
    - loop iteration
        ```
        for os in platforms {
          print("Swift works great on \(os)")
        }
        ```
    - loop variable： `os`
- ex: 指定一個動作重複做幾次
    ```
    for i in 1...12 {
      print("5 x \(i) = \(5 * i)")
    }
    
    // 5 x 1 = 5
    5 x 2 = 10
    5 x 3 = 15
    5 x 4 = 20
    5 x 5 = 25
    5 x 6 = 30
    5 x 7 = 35
    5 x 8 = 40
    5 x 9 = 45
    5 x 10 = 50
    5 x 11 = 55
    5 x 12 = 60
    ```
    - loop variable的命名convention: `i` -> `j` -> `k`
- ex: 巢狀（nested）loop，在loop裡面再多幾層loop
    ```
    for i in 1...3 {
      print("The \(i) times table")

      for j in 1...5 {
        print("    \(j) * \(i) is \(j * i)")
      }

      print()
    }
    
    // The 1 times table
    1 * 1 is 1
    2 * 1 is 2
    3 * 1 is 3
    4 * 1 is 4
    5 * 1 is 5

    The 2 times table
        1 * 2 is 2
        2 * 2 is 4
        3 * 2 is 6
        4 * 2 is 8
        5 * 2 is 10

    The 3 times table
        1 * 3 is 3
        2 * 3 is 6
        3 * 3 is 9
        4 * 3 is 12
        5 * 3 is 15
    ```
- 只想loop不含最後一個數字的情況： `..<`
    ```
    for i in 1...5 {
      print("Counting from 1 through 5: \(i)")
    }
    
    // Counting from 1 through 5: 1
    Counting from 1 through 5: 2
    Counting from 1 through 5: 3
    Counting from 1 through 5: 4
    Counting from 1 through 5: 5

    for i in 1..<5 {
      print("Counting from 1 up to 5: \(i)")
    }
    
    // Counting from 1 up to 5: 1
    Counting from 1 up to 5: 2
    Counting from 1 up to 5: 3
    Counting from 1 up to 5: 4
    ```
- 有時候不需要用到loop variable，可以用 `_` 代替
    ```
    var lyric = "Haters gonna"

    for _ in 1...5 {
      lyric += " hate"
    }

    print(lyric)
    
    // Haters gonna hate hate hate hate hate
    ```
    
### Optional: Why does Swift use underscores with loops?

- Swift能檢查你是否在 loop 裡有用到 loop variable，如果沒有的話，會在你命名loop variable時報錯，請你改為 `_` ，這樣在看 code 的時候一眼就能看出這段 loop 沒有使用到該 variable

### Optional: Why does Swift have two range operators?

- 「範圍是否要包含指向的最後一個數字」在實務中是很常見的問題，因此Swift提供兩種範圍運算子：`...`（包含後者）及 `..<`（不包含後者）
    - `...`: 1 through 5
    - `..<`: 1 to 5
- 如果不確定最後的index，可以這樣： `print(names[1...])` 取得從index為1的值到 array 的最後一個值
    
## How to use a while loop to repeat work

- 給定一個條件，Swift的 `while` 會一直重複執行動作直到該條件不再符合
- `for` loop還是比 `while` loop 更常被使用
    ```
    var countdown = 10

    while countdown > 0 {
      print("\(countdown)")
      countdown -= 1
    }

    print("Blast off!")
    
    // 10
    9
    8
    7
    6
    5
    4
    3
    2
    1
    Blast off!
    ```
- `while` 在不知道確切要執行幾次的情況下很好用
    ```
    var roll = 0

    while roll != 20 {
      roll = Int.random(in: 1...20)
      print("I rolled a \(roll)")
    }

    print("Critical hit!")
    
    // I rolled a 19
    I rolled a 7
    I rolled a 19
    I rolled a 13
    I rolled a 13
    I rolled a 16
    I rolled a 16
    I rolled a 20
    Critical hit!
    ```
    - `random(in: )` ：在某範圍內隨機產生一個值

### Optional: When should you use a while loop?

- `for` loop 通常是用在有限的情況下，例如從數字1到10、或遍歷一個array中的items
- `while` loop 則是可以一直重複直到一個任意的條件變成false，例如使用者要求停止、伺服器要求停止、找到要找的答案、產生足夠的資料等條件
- 有時候就是無法預料某情況會需要loop幾次，所以需要用 `while` 來判斷

## How to skip loop items with break and continue

#### continue

- 在沒有指定 `continue` 的情況下，loop一旦遇到不符合條件的item就會終止
- 但某些情況下，我們希望loop跳過不符合條件的item，然後繼續跑完剩下的loop
    ```
    let filenames = ["me.jpg", "work.txt", "Sophie.jpg"]

    for filename in filenames {
      if filename.hasSuffix(".jpg") == false {
        continue
      }
      print("Found picture: \(filename)")
    }
    
    // Found picture: me.jpg
    Found picture: Sophie.jpg
    ```
    
#### break

- 在某條件下 `break`，會立即終止loop，不論後面是否還有item
    ```
    let number1 = 4
    let number2 = 14
    var multiples = [Int]()

    for i in 1...100_000 {
      if i.isMultiple(of: number1) && i.isMultiple(of: number2) {
        multiples.append(i)

        if multiples.count == 10 {
          break
        }
      }
    }

    print(multiples)
    
    // [28, 56, 84, 112, 140, 168, 196, 224, 252, 280]
    ```
    
### Optional: Why would you want to exit a loop?

- 某些情況下，不需要遍歷整個array或range就可以得到答案，這時使用 `break` 可以節省時間或運算，例如要計算玩家連續幾局沒有得到0分，當一遇到0分就 `break`

### Optional: Why does Swift have labeled statements?

- 在 nested loops 的情況下，如果需要在某條件發生時一次結束所有loop ，可以為最外層的 loop 取名，`break` 時直接指定該 loop 名即可
    ```
    outerLoop: for option1 in options {
        for option2 in options {
            for option3 in options {
                print("In loop")
                let attempt = [option1, option2, option3]

                if attempt == secretCombination {
                    print("The combination is \(attempt)!")
                    break outerLoop
                }
            }
        }
    }
    ```
    
### Optional: When to use break and when to use continue

- `continue` 代表的是跳過「目前執行的項目」； `break` 則是跳過「剩下的所有項目」
    
## Summary: Conditions and loops

- 我們用 `if` 、 `else` 、 `else if` 來檢查條件
- 可以用 或（`||`）、且（`&&`） 來結合不同條件
- `switch` 使用起來會比 `if` 、 `else if` 容易，而且Swift會檢驗它們是否覆蓋了所有可能情況
- 三元運算子讓我們檢驗「WTF」，`What?` ? `True` : `False`
- `for` loop 讓我們在 `array` 、 `set` 、 `dictionary` 或一定範圍內重複執行某動作
- `while` loop 重複執行某動作直到該條件不符合
- 用 `continue` 或 `break` 以不同方式跳過loop