【Lua 筆記】陣列 - part 5
===
目錄(Table of Contents):
[TOC]
---
由於有款遊戲叫做 CSO(Counter-Strike Online),內建模式創世者模式(Studio)新增使用 Lua 及其遊戲的 API,所以突發奇想製作這個筆記。
這個筆記會在一開始先著重純粹的程式設計自學,在最後的章節才會與 CSO 遊戲 API 進行應用。
陣列(Array)
---
我們先來看看 Lua 的陣列長怎樣:
```lua=
myArray = {10, 20, 30, 40, 50}
```
陣列(Array),用兩個大括號 `{}` 將資料圍起來,在 Lua 當中並沒有給它特定的資料型態,而是被一個稱為 table(表)的資料型態所包圍起來。
所以 type(myArray) 輸出結果會是 table:
```lua=
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。
### 擷取陣列值
---
```lua=
myArray = { 10, 20, 30, 40, 50 }
print(myArray[1]) --> 10
print(myArray[2]) --> 20
print(myArray[3]) --> 30
```
擷取陣列值很簡單,只需要打上陣列的變數名稱(myArray),加上 [] 兩個左右中括號,裡面填上各個數字的位置(索引值:index)即可。
不過這樣似乎太麻煩了,所以我們可以運用 for 迴圈幫我們完成這件事情:
```lua=
myArray = { 10, 20, 30, 40, 50 }
for i = 1, 3 do
print(myArray[i])
end
```
輸出結果:
```
10
20
30
```
### 計算陣列長度
---
計算陣列長度,我們可以使用 `#` 運算子,使回傳陣列的長度(意即得知陣列的元素個數)。
註:以 myArray = {10, 20, 30, 40, 50} 為例,10、20、30 這些被稱為陣列當中的元素(element)。
```lua=
myArray = { 10, 20, 30, 40, 50 }
print(#myArray) --> 5
```
透過計算陣列長度,我們能夠使用 for 迴圈來幫我們完成「遍歷」陣列這件事情。
註:遍歷(traversal),簡單來說就是從頭到尾一個一個拜訪、跑過一遍。以陣列而言就是從第一個元素跑到最後一個。
```lua=
myArray = { 10, 20, 30, 40, 50 }
for i = 1, #myArray do
print(myArray[i])
end
```
輸出結果:
```
10
20
30
40
50
```
不過習慣上,筆者通常會寫成這樣:
```lua=
myArray = { 10, 20, 30, 40, 50 }
length = #myArray
for i = 1, length do
print(myArray[i])
end
```
筆者習慣使用變數儲存值,因為方便的緣故,不用每次打上原文(#myArray)。
### 陣列索引值問題
---
我們將 i = 1,改成 i = 0 看看執行起來會怎樣:
```lua=
myArray = { 10, 20, 30, 40, 50 }
for i = 0, #myArray do --> 將 i = 1 改成 i = 0
print(myArray[i])
end
```
輸出結果:
```
nil
10
20
30
40
50
```
多了一個 nil,因為我們沒有設定索引 0 的陣列值,所以 lua 他找不到,回傳值就是空。
寫成以下這樣,設定索引 0 的值:
```lua=
myArray = { 10, 20, 30, 40, 50 }
myArray[0] = 0
for i = 0, #myArray do
print(myArray[i])
end
```
輸出結果:
```
0
10
20
30
40
50
```
也可以將索引改成負數喔!這部分就請自行練習~
### 二維陣列(Two dimensional Arrays)
---
二維陣列,顧名思義,就是陣列裡面還有一個陣列:
```lua=
myArray = {{1,2,3,4,5}, {6,7,8,9,10}, {11,12,13,14,15}}
```
這樣的寫法完全沒問題喔!而且應用在很多地方,例如像是高中數學的矩陣運算(矩陣乘法、加法、鏡射矩陣等),以及顯示卡繪圖應用。
以下是遍歷二維陣列的程式碼:
```lua=
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
```
以上的 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
也可以是負數。
二維陣列,顧名思義,就是陣列裡面還有一個陣列:
```lua=
myArray = {{1,2,3,4,5}, {6,7,8,9,10}, {11,12,13,14,15}}
```
參考資料
---
[Lua 数组 | 菜鸟教程](https://www.runoob.com/lua/lua-arrays.html)
[【30天Lua重拾筆記19】基礎3: 陣列從1開始 | 又LAG隨性筆記](https://www.lagagain.com/post/30%E5%A4%A9lua%E9%87%8D%E6%8B%BE%E7%AD%86%E8%A8%9819%E9%99%A3%E5%88%97%E5%BE%9E1%E9%96%8B%E5%A7%8B/)