【Lua 筆記】陣列 - part 5

由於有款遊戲叫做 CSO(Counter-Strike Online),內建模式創世者模式(Studio)新增使用 Lua 及其遊戲的 API,所以突發奇想製作這個筆記。

這個筆記會在一開始先著重純粹的程式設計自學,在最後的章節才會與 CSO 遊戲 API 進行應用。

陣列(Array)

我們先來看看 Lua 的陣列長怎樣:

1
myArray = {10, 20, 30, 40, 50}

陣列(Array),用兩個大括號 {} 將資料圍起來,在 Lua 當中並沒有給它特定的資料型態,而是被一個稱為 table(表)的資料型態所包圍起來。

所以 type(myArray) 輸出結果會是 table:

1
2
myArray = {10, 20, 30, 40, 50}
print(type(myArray)) --> table

:::danger
切記:Lua 的陣列索引從 1 開始。也可以自定義從 0 開始,等下會說怎麼做。
:::

回歸到問題本身,各位可能仍然還會疑惑的一點是,陣列到底是啥?

陣列你也可以想像成是數學上的「數列」,而剛剛說的索引,其實就是數列當中,數字的「位置」編號。

以 myArray = {10, 20, 30, 40, 50} 為例:

是一個長度為 5 的陣列,陣列裡面的 10 的索引值是 1,40 的索引值是 4。

擷取陣列值

1
2
3
4
myArray = { 10, 20, 30, 40, 50 }
print(myArray[1]) --> 10
print(myArray[2]) --> 20
print(myArray[3]) --> 30

擷取陣列值很簡單,只需要打上陣列的變數名稱(myArray),加上 [] 兩個左右中括號,裡面填上各個數字的位置(索引值:index)即可。

不過這樣似乎太麻煩了,所以我們可以運用 for 迴圈幫我們完成這件事情:

1
2
3
4
myArray = { 10, 20, 30, 40, 50 }
for i = 1, 3 do
print(myArray[i])
end

輸出結果:

1
2
3
10
20
30

計算陣列長度

計算陣列長度,我們可以使用 # 運算子,使回傳陣列的長度(意即得知陣列的元素個數)。

註:以 myArray = {10, 20, 30, 40, 50} 為例,10、20、30 這些被稱為陣列當中的元素(element)。

1
2
myArray = { 10, 20, 30, 40, 50 }
print(#myArray) --> 5

透過計算陣列長度,我們能夠使用 for 迴圈來幫我們完成「遍歷」陣列這件事情。

註:遍歷(traversal),簡單來說就是從頭到尾一個一個拜訪、跑過一遍。以陣列而言就是從第一個元素跑到最後一個。

1
2
3
4
myArray = { 10, 20, 30, 40, 50 }
for i = 1, #myArray do
print(myArray[i])
end

輸出結果:

1
2
3
4
5
10
20
30
40
50

不過習慣上,筆者通常會寫成這樣:

1
2
3
4
5
myArray = { 10, 20, 30, 40, 50 }
length = #myArray
for i = 1, length do
print(myArray[i])
end

筆者習慣使用變數儲存值,因為方便的緣故,不用每次打上原文(#myArray)。

陣列索引值問題

我們將 i = 1,改成 i = 0 看看執行起來會怎樣:

1
2
3
4
myArray = { 10, 20, 30, 40, 50 }
for i = 0, #myArray do --> 將 i = 1 改成 i = 0
print(myArray[i])
end

輸出結果:

1
2
3
4
5
6
nil
10
20
30
40
50

多了一個 nil,因為我們沒有設定索引 0 的陣列值,所以 lua 他找不到,回傳值就是空。

寫成以下這樣,設定索引 0 的值:

1
2
3
4
5
myArray = { 10, 20, 30, 40, 50 }
myArray[0] = 0
for i = 0, #myArray do
print(myArray[i])
end

輸出結果:

1
2
3
4
5
6
0
10
20
30
40
50

也可以將索引改成負數喔!這部分就請自行練習~

二維陣列(Two dimensional Arrays)

二維陣列,顧名思義,就是陣列裡面還有一個陣列:

1
myArray = {{1,2,3,4,5}, {6,7,8,9,10}, {11,12,13,14,15}}

這樣的寫法完全沒問題喔!而且應用在很多地方,例如像是高中數學的矩陣運算(矩陣乘法、加法、鏡射矩陣等),以及顯示卡繪圖應用。

以下是遍歷二維陣列的程式碼:

1
2
3
4
5
6
7
myArray = {{1,2,3,4,5}, {6,7,8,9,10}, {11,12,13,14,15}}

for i=1, #myArray do
for j=1, #myArray[i] do
print(myArray[i][j])
end
end

輸出結果:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

以上的 for 迴圈屬於巢狀迴圈,說明一下~:

  • i = 1 時,直接進入下一層迴圈 j = 1 ~ #myArray[i] 的循環。
  • i 要變成 2 之前,必須要等 j 這個內層迴圈跑完才可以。
  • 以此類推。

總結

陣列(Array),在 Lua 當中並沒有給它特定的資料型態,而是被一個稱為 table(表)的資料型態所包圍起來。

:::danger
切記:Lua 的陣列索引從 1 開始。也可以自定義從 0 開始。
:::

陣列你也可以想像成是數學上的「數列」,而剛剛說的索引,其實就是數列當中,數字的「位置」編號。

擷取陣列值:myArray[index],擷取 index 位置上的資料。

計算陣列長度:用 # 運算子,使回傳陣列的長度(意即得知陣列的元素個數)。

例:#myArray

Lua 陣列的索引是可以自定義的,例如:

myArray[0] = 0

也可以是負數。

二維陣列,顧名思義,就是陣列裡面還有一個陣列:

1
myArray = {{1,2,3,4,5}, {6,7,8,9,10}, {11,12,13,14,15}}

參考資料

Lua 数组 | 菜鸟教程

【30天Lua重拾筆記19】基礎3: 陣列從1開始 | 又LAG隨性筆記