程式扎記: [ Ruby Gossip ] Basic : 內建型態與操作 - 陣列型態

標籤

2014年10月8日 星期三

[ Ruby Gossip ] Basic : 內建型態與操作 - 陣列型態

Source From Here 
Preface 
在Ruby中,陣列為有序的物件集合,具有索引特性,長度可以變動。要建立陣列,可以使用 [] 實字,串列中每個元素,使用逗號 , 區隔。例如: 
 

陣列型態 
使用 [] 建立陣列物件,為 Array 的實例,若沒有指定任何元素,長度為 0。你可以對陣列使用 push相當於使用 << 操作)、poplast 方法對末端進行附加、取出、讀取元素,也就是進行堆疊(Stack)操作。使用 unshiftshiftfirst 對前端進行加入、取出、讀取元素,也就是進行佇列(Queue)操作。可以使用 insertdeletereverse 等方法進行安插、刪除、反轉等動作,使用include? 測試元素是否在陣列中,使用 length 取得陣列長度。 

果要對陣列中的元素進行排序,可以使用 sort 方法。例如: 
>> array = [3, 1, 4, 5, 2, 7]
=> [3, 1, 4, 5, 2, 7]
>> array.sort
=> [1, 2, 3, 4, 5, 7]
>> array.sort { |a, b| b <=> a }
=> [7, 5, 4, 3, 2, 1]
>> array
=> [3, 1, 4, 5, 2, 7] # 原本 array 內容不變

sort 方法可以自行指定排序方式,上例中第二個 sort 範例,{} 區塊中會傳入陣列中兩元素給 a、b 參考,你要傳回 0、大於0 或 小於0,表示順序上 a 等於 b、a 大於 b 及 a 小於 b,<=> 操作左邊若大於右邊會傳回 1,等於右邊會傳回0,小於右邊會傳回 -1,在 Ruby 區塊中,最後一個運算的結果會作為傳回值,因此第二個 sort 範例就完成陣列中反序排列。 

如果要附加多個元素,則可以使用 + 操作,注意與 << 操作的不同。例如: 
>> array1 = [1, 2, 3]
=> [1, 2, 3]
>> array1 << [4, 5, 6]
=> [1, 2, 3, [4, 5, 6]]
>> array2 = [1, 2, 3]
=> [1, 2, 3]
>> array2 + [4, 5, 6]
=> [1, 2, 3, 4, 5, 6]

可以對陣列使用 *,指定加倍陣列的內容,注意對每個元素是進行淺層複製(Shallow copy): 
>> array1 = [[1, 2, 3], [4, 5, 6]]
=> [[1, 2, 3], [4, 5, 6]]
>> array2 = array1 * 2
=> [[1, 2, 3], [4, 5, 6], [1, 2, 3], [4, 5, 6]]
>> array2[0][0] = 100
=> 100
>> array2
=> [[100, 2, 3], [4, 5, 6], [100, 2, 3], [4, 5, 6]]
>> array1
=> [[100, 2, 3], [4, 5, 6]]

* 也可以用來拆解陣列,如果你要將陣列中的元素一次指定給數個變數時會很方便: 
>> x, y, z = *[10, 20, 30]
=> [10, 20, 30]
>> x
=> 10
>> y
=> 20
>> z
=> 30
>> x, y, z = [40, 50, 60]
=> [40, 50, 60]
>> x
=> 40
>> y
=> 50
>> z
=> 60

實際上可以看到,如果只是指定給變數,並不需要特別加上 *,之後會看到,如果要將陣列指定給 方法 上的參數,才需要特別指定 *。 

* 也可以用來收集資料為陣列,例如: 
>> *a = 1, 2, 3
=> [1, 2, 3]
>> a = [1, 2, 3]
=> [1, 2, 3]
>> a = 1, 2, 3
=> [1, 2, 3]

實際上要收集資料為陣列,只要在等號右邊以逗號區隔就可以了,結合以上說明,在Ruby中要交換變數,只要這麼作: 
>> x = 10
=> 10
>> y = 20
=> 20
>> x, y = y, x # swap x,y
=> [20, 10]
>> x
=> 20
>> y
=> 10

因為=右邊若有逗號區隔的資料,會收集為陣列,陣列若指定給右邊變數,會拆解並分配給各個變數,因而組成了簡單的交換變數語法。 

在 Ruby 中,陣列可以進行集合(Set)運算,使用 & 可作交集運算,使用 | 可作聯集運算,使用 - 作減集運算。例如: 
>> admins = ["Justin", "caterpillar"]
=> ["Justin", "caterpillar"]
>> users = ["momor", "hamini", "Justin"]
=> ["momor", "hamini", "Justin"]
>> admins & users
=> ["Justin"]
>> admins | users
=> ["Justin", "caterpillar", "momor", "hamini"]
>> admins - users
=> ["caterpillar"]

陣列不提供 XOR 運算,不過可以自己製作一個: 
 

你也可以直接使用 [] 指定索引來取得元素、修改元素甚至安插元素,索引可以是負數,也可以進行切片(Slice)運算。例如: 
>> array = ["one", "two", "three", "four"]
=> ["one", "two", "three", "four"]
>> array[0]
=> "one"
>> array[0] = 1
=> 1
>> array
=> [1, "two", "three", "four"]
>> array[1..3]
=> ["two", "three", "four"]
>> array[1...3]
=> ["two", "three"]
>> array[1..2] = [2, 3]
=> [2, 3]
>> array
=> [1, 2, 3, "four"]
>> array[-1]
=> "four"
>> array[-2]
=> 3
>> array[1, 3]
=> [2, 3, "four"]
>> array[1, 9]
=> [2, 3, "four"]
>> array[1, -1]
=> [2, 3, "four"]
>> array[1..9]
=> [2, 3, "four"]
>> array[1, 3] = ["two", "three", 4]
=> ["two", "three", 4]
>> array
=> [1, "two", "three", 4]
>> array[1, 0] = [2, 3] # 在位置 1 插入 [2, 3]
=> [2, 3]
>> array
=> [1, 2, 3, "two", "three", 4]
>> array[1..0] = ["two", "three"] # 在位置 1 插入 ["two", "three"]
=> ["two", "three"]
>> array
=> [1, "two", "three", 2, 3, "two", "three", 4]


[n..m]可 指定起始索引與結束索引,且包括結束索引以取得元素,如果結束索引超出了陣列範圍,就是直接取到最後一個索引元素, [n...m]可 指定起始索引與結束索引,但包括結束索引以取得元素(實際上 n..m 或 n...m 建立了 Range 實例,之後會再說明)。[n, length]可指定起始索引與長度取得元素,如果長度超出了剩餘長度,就是直接取到最後一個元素。[n..m]、[n...m]或[n, length]右邊接上=,表示作取代的動作,如果指定了[n..0]、[n...0]或[n, 0],則是技巧性地作了安插的動作。 

你也可以使用 Array.new 方式建立陣列。例如: 
>> array = Array.new(5)
=> [nil, nil, nil, nil, nil]
>> array = Array.new(5, 10)
=> [10, 10, 10, 10, 10]
>> array = Array.new(5, [1, 2, 3])
=> [[1, 2, 3], [1, 2, 3], [1, 2, 3], [1, 2, 3], [1, 2, 3]]
>> array[0][0] = "one"
=> "one"
>> array
=> [["one", 2, 3], ["one", 2, 3], ["one", 2, 3], ["one", 2, 3], ["one", 2, 3]]

Array.new 第一個參數為陣列長度,第二個為每個索引預設元素,如果沒有指定則預設為nil,注意 Array.new(5, [1, 2, 3]) 的陷阱,實際上五個索引都會參考至同一個 [1, 2, 3] 物件,如果你希望五個索引參考至不同的陣列物件,必須如下: 
 

使用 Array.new 時,區塊中最後一個運算的結果會作為傳回值,上例中,會執行五次區塊內容,每次依陣列實字(Array literal)產生一個新的 [1, 2, 3] 陣列,因此五個索引就會參考不同的陣列物件。如果想得知目前是要建立第幾個索引的元素,可以如下: 
 

如果想循序走訪元素,可以有幾個方式: 
 

如果要建立字串陣列,有個方便的 %w 可以使用。例如: 
>> %w[Python JavaScript Ruby]
=> ["Python", "JavaScript", "Ruby"]

用來包括元素內容的符號,不一定要用[],也可以使用自己想用的符號,以不與字串中字元重複為原則。例如: 
>> %w
=> ["Python", "JavaScript", "Ruby"]
>> %w|Python JavaScript Ruby|
=> ["Python", "JavaScript", "Ruby"]

Supplement 
tutorialpoint - Arrays 
Ruby arrays are ordered, integer-indexed collections of any object. Each element in an array is associated with and referred to by an index...

Rubylearning.com - Arrays

沒有留言:

張貼留言

網誌存檔

關於我自己

我的相片
Where there is a will, there is a way!