Ruby學習筆記3,第四章
數(shù)組
Ruby的數(shù)組不是homogen的,可以保存不同的類型,包括數(shù)組
a = [ 3.14159, "pie", 99 ]
a.class => Array
a.length => 3
a[0] => 3.14159 # Index以0開始
a[3] => nil # 沒有異常,返回nil
a[-1] => 99 # Index -1 返回最后一個元素
a[-a.length] => 3.14159 # 返回第一元素
數(shù)組的負Index和Python中的一樣。
b = Array.new
b[100] = 1
a = [ 1, 3, 5, 7, 9 ]
a[3, 2] => [ 7, 9 ] # 從Index3開始,取2個
a[-3, 2] => [ 5, 7 ] # 從倒數(shù)第3個開始取2個
兩種Ranges,在Pascal是見過其中一種, ..
1..100 表示1到100
1...100 表示1到99, 不包括100
-5..-1 表示-5, -4, -3, -2, -1
三點的Range不包括第二個端點
a[-3..-1] # 取最后3個元素
a[4..-2] # 從第4個元素起(從0開始計數(shù)),取到倒數(shù)第二個
如果Range的第二個端點在第一個前面,返回空數(shù)組[], 比如假設(shè)a只有5個元素,a[4..-2] => []
修改數(shù)組
a = [ 1, 3, 5, 7, 9 ]
a[2, 2] = 'cat' => a = [ 1, 3, 'cat', 9 ] # 刪除左邊[2, 2]選定的區(qū)域,插入右邊的元素
a[2, 0] = 'dog' => a = [ 1, 3, 'dog', 'cat', 9 ] # 如果左邊選定的區(qū)域為空,相當于插入元素
a[1, 1] = [ 9, 8, 7 ] => a = [ 1, 9, 8, 7, 'dog', 'cat', 9 ] # 右邊為數(shù)組,逐個插入
a[0..3] = [] => a = [ 'dog', 'cat', 9 ] # 右邊為空,相當于刪除
a[5..6] = 99, 98 => a = [ 'dog', 'cat', 9, nil, nil, 99, 98 ]
Block
Ruby的Block中的變量的Scope比較混亂,看下面這段代碼



defined?(c)返回nil. 規(guī)律是,如果變量已定義,則用之,否則是Block的局部變量,在Block之外不可見。這一特性可能在Ruby2.0中修改。
Block的最后一個表達式的值作為yield的返回值。
Iterator
遍歷在Ruby中有多種不同的實現(xiàn)方式
each對每個元素做點什么
[1, 2, 3, 4].each { |x| puts x }
collect對每個元素調(diào)用Block,用返回的值重新組成數(shù)組
[1, 2, 3, 4].collect { |x| x+1 } => [2, 3, 4, 5]
["A", "B"].collect { |x| x.succ } => ["B", "C"]
collect類似maplist, 只不過maplist的函數(shù)參數(shù)在這里是Block。
inject對每個元素調(diào)用Block計算值,并用一個變量將值傳遞到Block的下次調(diào)用。
[1, 2, 3, 4].inject(0) { |sum, x| sum + x } => 10
執(zhí)行過程如下
sum = 0 # inject的輸入?yún)?shù)
for each element x
sum = yield(sum, x)
end
return sum
所有的each可以方便的用inject實現(xiàn)
[1, 2, 3, 4].inject(0) { |s, x| puts x } 等效于 [1, 2, 3, 4].each { |x| puts x }, 除了返回值不同
求一個數(shù)組里所有數(shù)的乘積
[1, 2, 3, 4].inject(1) { |prod, x| prod * x }
也可以寫成
[1, 2, 3, 4].inject { |prod, x| prod * x }
如果inject不帶參數(shù),prod先為第一個元素,從第二個元素開始遍歷。
inject這個名字不是很恰當,還不如用accumulate。
block_given?函數(shù)判斷是否帶有Block調(diào)用
函數(shù)參數(shù)
def foo(*args)的參數(shù)個數(shù)是任意,*args收集參數(shù)作為一個數(shù)組,比如foo(1, 2, 3), args = [1, 2, 3]
Proc
Block是匿名的,如果一個函數(shù)的最后一個參數(shù)名以&打頭,那么要求一個Block。Block還可以用lambda轉(zhuǎn)化為Proc對象,Proc可以用call方法調(diào)用。
proc = lambda { |x, y| x + y }
proc.call(1, 2) => 3
def n_times(thing)
lambda { |n| n * thing }
end
p1 = n_times(23)
p1.call(3) => 69
p2 = n_times("Hello ")
p2.call(3) => "Hello Hello Hello "
n_times的參數(shù)thing在新生成的Proc中還存在,這種性質(zhì)在其他語言中稱為Closure。
轉(zhuǎn)載請保留http://www.aygfsteel.com/xilaile/archive/2007/05/06/115624.html