迴圈可以讓一個動作不斷重複,可以讓你對每個個別的元素做事、設定重複的次數,可以讓一個程式運行直到使用者想停止。
從我最常用的迴圈開始,Each 迴圈。
each 迴圈讓可以執行一個列表的次數(看列表有多少東西),不需要迭代或計數器,這是 ruby “重複直到結束” 方法。在使用之前需要搜集資料到一個陣列、範圍或雜湊。
numbers = [1, 3, 5, 7]
然後就可以使用 each:
numbers.each { |n| puts n }
用白話文來敘述就是說“印出每個在 numbers 裡的元素”,用 block 告訴 each 方法要對每個項目做什麼,在這個例子裡在 each 後面是一個 block:
{ |n| puts n }
each 在 block 做的事情就是把每個元素個別帶到 n 裡面然後執行 block 裡面的動作。
迴圈的目的就是去迭代或是訪問每個在表單裡的元素,表單可以是許多形式但通常都是陣列居多。有許多方法可以用端看當下的狀況。最常見的是用 each 方法,因為不需要保持表單裡的軌跡。
Ruby 幫你做了困難的部分也給你一個 n 變數代表每個個別元素,n變數也可以隨你選擇只要是有效變數就可以。
如果你想要在雜湊使用 each 你就需要兩個參數,一個是給 key & 另一個是給值。剩下的語法都一樣你還是需要一個 block。
hash = { bacon: 300, coconut: 200 }
hash.each { |key,value| puts "#{key} price is #{value}" }
如果想要用 each 方法又需要 index 數字,你可以使用 each_with_index 方法:
animals = ["cat", "dog", "tiger"]
animals.each_with_index { |animal, idx| puts "We have a #{animal} with index #{idx}" }
這個方法可以讓你在一個陣列迴圈裡存取一個 index,請記住 index 的值都是從 0 開始。
這應該是最簡單的迴圈了。
10.times { puts "hello" }
這段程式碼會印出 10 次 "hello",也沒有其他東西可以加進去,應該也是最好記得迴圈。如果要那個數字呢?在 each 迴圈可以存取 n 變數如果是 times 迴圈就可以這樣做:
10.times { |i| puts "hello #{i}" }
這會印出 hello 0, hello 1, hello 2 ...
這裡的關鍵是有一個 |i| 的東西,可以命名為任意有效變數。沒有一定要 |i|,也可以是 |n| 、 |foo| 或 |bacon|...就只是一個名稱。如果對方法熟悉的話 |n| 就像是一個方法的參數。
或許有注意到當使用 times 方法的時候是從 0 開始跑。如果你想從其他數字開始的話,這或許會有一點不方便。你可以使用一個範圍,然後用 each 跑迴圈。像是這樣ㄤ
(1..10).each { |i| puts i }
這樣就會從 1 開始印到 10。
while 迴圈在大多數的程式語言都有用所以一定要知道。這是一種當其他東西有錯誤的時候可以倒退的迴圈。有其他的狀況像是如果你不知道迴圈要跑幾次的話:
n = 0
while n < 10
puts n
n += 1
end
這會印出 0..9(10除外)
注意有些重要的結構:
n 變數
條件 (n < 10)
n += 1
這些都是重要的結構。
n 變數有迴圈需要的值,條件 (n < 10) 告訴 ruby 何時停止迴圈(當 n 的值大於或等於 10), n += 1 會在每次迴圈增加計數器的值。如果忘記在 while 迴圈增加計數器的值就會進入無窮迴圈,意思是程式會一直運行。
這是另一個關鍵字 until,跟 while 很像只是條件是相反的。假設要用 until 迴圈讓水瓶裝滿,就可以說“直到在水瓶裝滿之前都不要停止”,這是一個反向的敘述,要盡量避免因為這讓邏輯更難理解。
用 until 迴圈可以試著這樣敘述:
“直到在水瓶裝滿後停止”
這樣會使程式碼更自然更好閱讀跟理解。
bottle = 0
until bottle == 10
bottle += 1
end
假設說要處理陣列裡的數字但是想要略過奇數。可以這樣做:
10.times do |i|
next unless i.even?
puts "hello #{i}"
end
在這裡用的語法就是 next,但是有更好的方法可以做到這件事像是 step & select 方法
(0...10).select(&:even?)
# [0, 2, 4, 6, 8]
在迴圈的條件達成之前或是跑過所有的元素之前也是可以跳出迴圈。下面的程式碼做的事情是當找到大於 10 的數字時跳出迴圈。
numbers = [1,2,4,9,12]
numbers.each do |n|
break if n > 10
puts n
end
在 ruby 的語法就是 break 。請記住,當使用 break 後就會立刻跳出迴圈,在 while 迴圈也是有作用的。
如果還不夠清楚, ruby 是非常有彈性的,還有一個 upto 方法可以創造迴圈。
1.upto(5) { |i| puts i }
可以印出 1 到 5。