# 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