Lua(table)
Lua table 基础概念
Lua 中的 table 是一种动态关联数组,可以存储任意类型的值(如数字、字符串、函数、甚至其他 table)。它既是数组又是字典,索引可以是数字或任意非 nil 值。
- 数组部分:索引从 1 开始(Lua 惯例),连续存储。
- 哈希部分:存储非连续或非数字索引的键值对。
创建 table
使用花括号 {}
创建空 table,或直接初始化内容:
-- 空 table
local t1 = {}-- 数组式初始化(索引隐式为 1, 2, 3...)
local t2 = {10, 20, 30}-- 字典式初始化
local t3 = {name = "Lua", version = "5.4"}-- 混合初始化
local t4 = {1, "two", name = "table", [5] = "five"}
访问和修改元素
通过 []
或 .
语法访问和修改元素:
local t = {x = 10, y = 20}-- 访问
print(t.x) -- 输出 10
print(t["y"]) -- 输出 20-- 修改
t.x = 100
t["y"] = 200
常用操作
插入元素
- 数组末尾插入:
table.insert(t, value)
- 指定位置插入:
table.insert(t, pos, value)
local arr = {1, 2, 3}
table.insert(arr, 4) -- 变为 {1, 2, 3, 4}
table.insert(arr, 2, 99) -- 变为 {1, 99, 2, 3, 4}
删除元素
- 移除末尾元素:
table.remove(t)
- 移除指定位置元素:
table.remove(t, pos)
local arr = {1, 2, 3, 4}
table.remove(arr) -- 移除 4,变为 {1, 2, 3}
table.remove(arr, 2) -- 移除 2,变为 {1, 3}
遍历 table
- 使用
pairs
遍历所有键值对(包括数组和哈希部分):
local t = {a = 1, b = 2, c = 3}
for k, v in pairs(t) doprint(k, v)
end
- 使用
ipairs
遍历数组部分(连续数字索引):
local arr = {1, 2, 3, x = 10}
for i, v in ipairs(arr) doprint(i, v) -- 输出 1 1, 2 2, 3 3(跳过 x = 10)
end
获取长度
#
操作符获取数组部分的长度(连续数字索引的最大值):
local arr = {1, 2, 3, nil, 5}
print(#arr) -- 输出 3(因为索引 4 是 nil)
- 对于哈希部分,需手动计算:
local function tableLength(t)local count = 0for _ in pairs(t) docount = count + 1endreturn count
end
排序
使用 table.sort(t, comp)
对数组部分排序(默认升序):
local arr = {3, 1, 4, 2}
table.sort(arr) -- 变为 {1, 2, 3, 4}-- 自定义排序规则
table.sort(arr, function(a, b) return a > b end) -- 降序
链接
table.concat
是 Lua 标准库中的一个函数,用于将数组(即连续数字索引的表)中的字符串元素连接成一个新的字符串。它通常用于高效拼接多个字符串,避免频繁的字符串创建和垃圾回收
table.concat(list [, sep [, i [, j]]])
- list: 需要连接的表(数组部分)。
- sep(可选): 分隔符,默认为空字符串
""
。 - i(可选): 起始索引,默认为
1
。 - j(可选): 结束索引,默认为表的长度
#list
。
local words = {"Hello", "world", "from", "Lua"}
local sentence = table.concat(words, " ")
print(sentence) -- 输出: "Hello world from Lua"
相比直接使用 ..
运算符拼接字符串,table.concat
在大量字符串拼接时性能更高,因为它减少了中间字符串的生成和内存分配。
高级操作
合并 table
手动合并两个 table:
local function mergeTables(t1, t2)local result = {}for k, v in pairs(t1) do result[k] = v endfor k, v in pairs(t2) do result[k] = v endreturn result
end
深拷贝
递归拷贝 table 的所有层级:
local function deepCopy(orig)local copy = {}for k, v in pairs(orig) doif type(v) == "table" thencopy[k] = deepCopy(v)elsecopy[k] = vendendreturn copy
end
元表(Metatable)
通过元表实现自定义行为:
local t = {10, 20, 30}
local mt = {__index = function(table, key)return "Key " .. key .. " not found"end,__add = function(t1, t2)local sum = {}for i = 1, math.max(#t1, #t2) dosum[i] = (t1[i] or 0) + (t2[i] or 0)endreturn sumend
}
setmetatable(t, mt)print(t[5]) -- 输出 "Key 5 not found"
local sum = t + {40} -- 调用 __add
性能注意事项
- 避免在循环中多次计算
#
或table.getn
。 - 大规模数据操作时,考虑预先分配数组大小(如
local arr = {}; for i=1,1000 do arr[i]=0 end
)。 - 哈希部分查找比数组部分慢,对性能敏感的场景尽量使用数字索引。
通过灵活运用这些操作,可以高效处理 Lua 中的复杂数据结构。