前言
原本在找Ruby要怎麼交換兩個陣列的位置,找到一個很神奇的方法
class Array
def swap!(a,b)
self[a], self[b] = self[b], self[a]
self
end
end
完全看不懂在幹嘛,如果是C語言,在同一行裡使用逗號,則表示從右到左依次執行而已,例如:
int i,j;
for(i=0,j=5;i<10;i++,j--);
在C語言這個迴圈共執行10次,每次都執行i++與j--,我把i++與j--寫在一起用逗號分開,其實也可以這麼寫
int i,j;
for(i=0,j=5;i<10;){
i++;
j--;
}
有時候為了簡潔會塞在同一行。
可是Ruby這麼做,我全看不懂在幹嘛,在文章開頭的swap!函式裡頭,self[a]在我眼裡就是回傳self[a],然後將self[b]賦值self[b]等於沒變,最後再回傳self[a]而已,完全不清楚這是怎麼swap。
Parallel Assignment
查了一下ruby-doc.com之後,找到了Parallel Assignment這個關鍵字,終於搞清楚了,Ruby會將等號右邊所有的物件,按照相對位置賦值到等號左邊的參數,就叫做Parallel Assignment,譬如你要將x,y,z分別賦值1,2,3,在C語言你可能這麼寫
int x=1, y=2, z=3;
在Ruby裡面可以這麼寫
x,y,z = 1,2,3
就是如此而已,x,y,z就分別被賦值1,2,3。
當然,像我這種宅宅,一定還會好好地玩弄一下,我故意讓等號兩邊無法成對:
1: a,b = 1,2,3 # a=1, b=2
2: i,j,k = 1,2 # i=1, j=2, k=nil
行1,我原本以為b會被賦值為陣列[2,3],其實不用這麼古怪,Ruby設計直接把多出來的3丟掉,聰明的設計。
行2,我原本以為會出現錯誤訊息,但這也太嚴謹了,Ruby直接讓k=nil就行了,也是聰明的設計。
接著繼續惡搞一下,看他的語法有沒有靈活性:
a,b = c=1, 2 # a=1, b=2, c=1
a,b = c,d = 1, 2, 3 # Compiler Error
# 編譯錯誤 所以自己加上括號
a,b = (c,d = 1, 2), 3 # a=[1,2], b=3, c=1, d=2
有趣唷Parallel Assignment會回傳一個陣列,所以很靈活
SWAP
既然如此,我們就可以利用Parallel Assignment,來進行簡潔的swap,將x,y兩數交換:
# Parallel Assignment 定初值
x,y = 1,2 # x=1, y=2
# 一樣用Parallel Assignment技巧交換兩數
x,y = y,x # x=2, y=1
你想要3個數字一起交換也可以
x,y,z = 1,2,3 # x=1, y=2, z=3
x,y,z = y,z,x # x=2, y=3, z=1
搞清楚之後,文章開頭提的那個陣列交換swap!函式就看得懂了
def swap!(a,b)
self[a], self[b] = self[b], self[a]
self
end
簡單將a,b兩個位置交換之後,最後把回傳陣列本身
沒有留言:
張貼留言