表 (table) 是 Lua 唯一的資料結構,在 Lua 內部的實作上,表帶有雜湊表 (hash table) 和陣列 (array) 兩種資料結構,Lua 會視需求自動呼叫適合的結構。對使用者來說,不需要去區分這些細節,把表當成關聯式陣列 (associative array) 來使用即可。
表有許多的用途,如下:
- 做為陣列 (array)
- 做為字典 (dictionary)
- 用於物件導向程式 (object-oriented programming)
- 模擬其他資料結構 (data structures)
本文著重前兩者,其他的用途於後文介紹。
以表做為陣列
陣列 (array) 是一種以數字為索引的線性資料結構,在 Lua 中是以表模擬。
以索引取值
我們也可以用數字做為索引 (index) 取值:
-- Create an array.
local arr = {"a", "b", "c", "d", "e"}
-- Retrieve the 3rd element.
assert(arr[3] == "c")
要注意的是,Lua 的陣列從 1 開始取索引,和大部分主流語言不同。
以下的陣列會造成空洞 (holes):
local arr = {}
arr[1] = "a"
arr[2] = "b"
-- arr[3] and arr[4] are nil
arr[5] = "c"
arr[6] = "d"
在 Lua 程式中,陣列的空洞會造成一些意想不到的 bug,應避免。
走訪陣列
使用 for
迴圈搭配 ipairs
函式可走訪陣列:
-- Create an array.
local arr = {"a", "b", "c", "d", "e"}
-- Iterate over the array.
for i, e in ipairs(arr) do
print(e)
end
也可以用數字為索引來走訪陣列:
-- Create an array.
local arr = {"a", "b", "c", "d", "e"}
-- Iterate over the array.
for i = 1, #arr do
print(arr[i])
end
取得陣列長度
Lua 用 #
(number sign) 取得陣列長度,見下例:
-- Create an array.
local arr = {"a", "b", "c", "d", "e"}
-- Check the length of the array.
assert(#arr == 5)
要注意的是,當陣列後端元素皆為 nil
時,不計入長度,見下例:
local arr = {10, 20, 30, nil, nil}
assert(#arr == 3)
注意此處 arr
的長度是 3
而不是 5
。
將元素插入陣列
利用 table.insert
可在尾端插入新的元素,見以下實例:
-- Create an array.
local arr = {"a", "b", "c", "d", "e"}
-- Check the length of the array.
assert(#arr == 5)
-- Append an element.
table.insert(arr, "f")
-- Recheck the length of the array.
assert(#arr == 6)
assert(arr[6] == "f")
或是使用 arr[#arr+1] = "f"
也可從尾端插入元素。
除了從尾端插入元素,也可從中間插入元素,見下例:
-- Create an array.
local arr = {"a", "b", "c", "d", "e"}
-- Check the length of the array.
assert(#arr == 5)
-- Insert an element at position 3.
table.insert(arr, 3, "f")
-- Recheck the length of the array.
assert(#arr == 6)
assert(arr[3] == "f")
從陣列中去除元素
使用 table.remove
可以從尾端去除元素,見下例:
-- Create an array.
local arr = {"a", "b", "c", "d", "e"}
-- Check the length of the array.
assert(#arr == 5)
-- Pop an element.
popped = table.remove(arr)
-- Recheck the length of the array.
assert(#arr == 4)
assert(popped == "e")
也可以從中間去除元素,見下例:
-- Create an array.
local arr = {"a", "b", "c", "d", "e"}
-- Check the length of the array.
assert(#arr == 5)
-- Remove an element from position 2.
removed = table.remove(arr, 2)
-- Recheck the length of the array.
assert(#arr == 4)
assert(removed == "b")
做為字典
字典是一種以鍵/值對 (key-value pairs) 為組合的非線性資料結構,以鍵為索引取值。
建立字典
以下實例建立一個字典:
-- Create an dictionary.
local dict = {
one="eins",
two="zwei",
three="drei"
}
-- Retrieve the value with the key.
assert(dict["one"] == "eins")
也可以先建立字典再逐一加入鍵值對:
-- Create an dictionary.
local dict = {}
-- Add some key/value pairs.
dict["one"] = "eins"
dict["two"] = "zwei"
dict["three"] = "drei"
-- Retrieve the value with the key.
assert(dict["one"] == "eins")
走訪字典
可以用 for
迴圈搭配 pairs
函式來走訪字典,見下例:
-- Create an dictionary.
local dict = {one="eins", two="zwei", three="drei"}
-- Iterate over the dictionary.
for k, v in pairs(dict) do
print(k .. ": " .. v)
end
註:注意 pairs
用來走訪字典,ipairs
用來走訪陣列。
從字典中去除鍵值對
若要去除元素,將其值設為 nil
即可,以下是實例:
-- Create an dictionary.
local dict = {one="eins", two="zwei", three="drei"}
-- Remove an key-value pair.
dict["three"] = nil
-- Retrieve some values.
assert(dict["one"] == "eins")
assert(dict["three"] == nil)