> 技术文档 > Lua(table)

Lua(table)


Lua table 基础概念

Lua 中的 table 是一种动态关联数组,可以存储任意类型的值(如数字、字符串、函数、甚至其他 table)。它既是数组又是字典,索引可以是数字或任意非 nil 值。

  • 数组部分:索引从 1 开始(Lua 惯例),连续存储。
  • 哈希部分:存储非连续或非数字索引的键值对。

创建 table

使用花括号 {} 创建空 table,或直接初始化内容:

-- 空 tablelocal 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) -- 输出 10print(t[\"y\"]) -- 输出 20-- 修改t.x = 100t[\"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) do print(k, v)end
  • 使用 ipairs 遍历数组部分(连续数字索引):
local arr = {1, 2, 3, x = 10}for i, v in ipairs(arr) do print(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 = 0 for _ in pairs(t) do count = count + 1 end return countend
排序

使用 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 end for k, v in pairs(t2) do result[k] = v end return resultend
深拷贝

递归拷贝 table 的所有层级:

local function deepCopy(orig) local copy = {} for k, v in pairs(orig) do if type(v) == \"table\" then copy[k] = deepCopy(v) else copy[k] = v end end return copyend
元表(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) do sum[i] = (t1[i] or 0) + (t2[i] or 0) end return sum end}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 中的复杂数据结构。

水族观赏鱼