Lua语法 | 6、表
本文介绍了Lua中表、ipairs和pairs的区别,并讲解了表中一些公共操作的使用方法。
一、表
在 Lua 中,表(table) 是唯一的数据结构机制,它既是数组又是字典(关联数组),同时也是实现模块、类和对象的基础。
(一)创建和初始化
-- 创建空表
local t1 = {}
-- 创建带有初始内容的表
local t2 = { "apple", "banana", "cherry" }
(二)移除引用
t1 = {}
-- 移除引用
t1 = nil
-- lua 垃圾回收会释放内存
当我们创建表 a 并设置元素,然后将 a 赋值给 b,则 a 与 b 都指向同一个内存。如果 a 设置为 nil ,则 b 同样能访问表的元素。如果没有指定的变量指向a,Lua的垃圾回收机制会清理相对应的内存。
例如:
a ={18,name="张三"}
print(a[1])
print(a.name)
--输出 18 张三
--表b和表a指的是同一个表
b = a
print(b[1])
print(b.name)
--输出 18 张三
print(a) --table: 00BB9C70
print(b) --table: 00BB9C70
--a和b指的是同一个表,修改b的元素,a的也跟着变化
b.name="麻子"
print(a.name)
print(b.name)
--输出 麻子 麻子
--释放变量
a = nil
print(a) --nil
print(b) --table: 00BB9C70
(三)访问元素
local t = { name = "John", age = 25, "first", "second" }
-- 访问字典元素
print(t.name) -- "John"
print(t["age"]) -- 25
-- 访问数组元素
print(t[1]) -- "first"
print(t[2]) -- "second"
(四)修改和添加元素
local t = {}
-- 添加元素
t[1] = "first"
t["name"] = "Alice"
t.new_key = "value"
-- 修改元素
t[1] = "updated first"
t.name = "Bob"
-- 删除元素
t[1] = nil
二 、表的遍历
(一)数字 for 循环
local numbers = {10, 20, 30, 40, 50}
-- 正向遍历
for i = 1, #numbers do
print(i, numbers[i])
end
-- 反向遍历
for i = #numbers, 1, -1 do
print(i, numbers[i])
end
-- 间隔遍历
for i = 1, #numbers, 2 do
print(i, numbers[i])
end
(二)迭代器遍历
1、ipairs - 遍历数组部分
ipairs 只遍历表的数组部分(连续的数字索引从1开始):
local fruits = {"apple", "banana", "cherry", "date"}
-- 只遍历数组部分
for index, value in ipairs(fruits) do
print(index, value)
end
-- 输出:
-- 1 apple
-- 2 banana
-- 3 cherry
-- 4 date
遇到 nil 会停止:
local t = {"a", "b", nil, "d", "e"}
for i, v in ipairs(t) do
print(i, v)
end
-- 输出:
-- 1 a
-- 2 b
-- 在 nil 处停止,不会输出 d 和 e
2、pairs - 遍历所有元素
pairs 会遍历表中的所有键值对,包括数组部分和哈希部分:
local person = {
name = "John",
age = 25,
city = "New York",
"first", -- 数组部分
"second" -- 数组部分
}
-- 遍历所有键值对
for key, value in pairs(person) do
print(key, value)
end
-- 可能的输出(顺序不确定):
-- 1 first
-- 2 second
-- name John
-- age 25
-- city New York
3、ipairs与pairs的区别
(1)遍历范围:
ipairs仅遍历表的数组部分,即从1开始的连续整数索引,直到遇到第一个nil值为止。pairs遍历表中的所有键值对,包括数组部分和哈希部分(非整数键)。
(2)遍历顺序:
ipairs保证按索引顺序遍历(1,2,3,...),直到连续整数索引中断。pairs的遍历顺序是不确定的,它可能以任意顺序遍历表中的键值对。
(3)性能:
ipairs在遍历数组部分时通常比pairs更快,因为它只需要按顺序访问整数索引。pairs需要处理哈希表结构,因此可能稍慢一些。
(4)使用场景:
- 当只需要遍历数组部分(连续整数索引)时,使用
ipairs。 - 当需要遍历整个表(包括非整数键)时,使用
pairs。
(5)遇到nil值的行为:
ipairs在遇到第一个nil值时停止遍历。pairs会跳过nil值,但会遍历所有非nil的键(包括整数和非整数键)。
三、表的操作
(一)连接
方法:table.concat (table , sep , start , end)
参数说明:
concat是concatenate(连锁, 连接)的缩写. table.concat()函数列出参数中指定table的数组部分从start位置到end位置的所有元素, 元素间以指定的分隔符(sep)隔开。
举例:
local fruits = {"banana","orange","apple"}
--返回连接后的字符串
print(table.concat( fruits)) --输出:bananaorangeapple
--指定连接字符
print(table.concat( fruits,",")) --输出:banana,orange,apple
--指定索引来连接表中元素
print(table.concat( fruits,",",2,3)) --输出:orange,apple
(二)插入
方法:table.insert (table , pos , value)
参数说明:
在table的数组部分指定位置(pos)插入值为value的一个元素. pos参数可选, 默认为数组部分末尾。
举例:
fruits = {"banana","orange","apple"}
-- 在末尾插入
table.insert(fruits,"mango")
print("索引为 4 的元素为 ",fruits[4])
--输出:索引为 4 的元素为 mango
-- 在索引为 2 的键处插入
table.insert(fruits,2,"grapes")
print("索引为 2 的元素为 ",fruits[2])
--输出:索引为 2 的元素为 grapes
--遍历表(fruits)
for k,v in pairs(fruits) do
print(k,v)
end
--[[
输出:
1 banana
2 grapes
3 orange
4 apple
5 mango
]]
(三)移除
方法:table.remove (table , pos)
参数说明:
返回table数组部分位于pos位置的元素. 其后的元素会被前移. pos参数可选, 默认为table长度, 即从最后一个元素删起。
举例:
fruits = {"banana","orange","apple"}
print("移除前最后一个元素为 ",fruits[#fruits])
--输出:移除前最后一个元素为 apple
table.remove(fruits)
print("移除后最后一个元素为 ",fruits[#fruits])
--输出:移除后最后一个元素为 orange
--遍历表(fruits)
for k,v in pairs(fruits) do
print(k,v)
end
--[[
输出:
1 banana
2 orange
]]
(四)排序
1、升序
方法:table.sort (table , comp)
参数说明:
对给定的table进行升序排序。
举例:
fruits = {"banana","orange","apple","grapes"}
print("排序前")
for k,v in ipairs(fruits) do
print(k,v)
end
table.sort(fruits)
print("排序后")
for k,v in ipairs(fruits) do
print(k,v)
end
--[[
排序前
1 banana
2 orange
3 apple
4 grapes
排序后
1 apple
2 banana
3 grapes
4 orange
]]
2、降序
方法:table.sort (table , function (a , b)
return a > b
end)
参数说明:
对给定的table进行降序排序。
举例:
fruits = {"banana","orange","apple","grapes"}
print("排序前")
for k,v in pairs(fruits) do
print(k,v)
end
table.sort(fruits,function(a,b)
return a>b
end)
print("排序后")
for k,v in pairs(fruits) do
print(k,v)
end
--[[
排序前
1 banana
2 orange
3 apple
4 grapes
排序后
1 orange
2 grapes
3 banana
4 apple
]]
3、table.sort(table,comp)中参数comp的作用
table.sort(table , comp) 中的 comp 参数是一个可选的比较函数,用于自定义排序的规则。
(1)comp 参数的基本作用
comp 函数决定了排序时元素之间的比较规则。它接收两个参数,返回一个布尔值:
function comp(a, b)
-- 如果返回 true,表示 a 应该排在 b 前面
-- 如果返回 false,表示 a 应该排在 b 后面
end
(2)默认行为(不使用 comp)
如果不提供 comp 函数,table.sort 使用默认的升序排序:
local numbers = {3, 1, 4, 1, 5}
table.sort(numbers) -- 默认升序
print(table.concat(numbers, ", ")) -- 输出: 1, 1, 3, 4, 5
这等价于:
table.sort(numbers, function(a, b)
return a < b -- 默认比较函数
end)
(3)常见 comp 函数用法
Ⅰ、降序排序
local numbers = {3, 1, 4, 1, 5}
table.sort(numbers, function(a, b)
return a > b -- 降序:大的在前
end)
print(table.concat(numbers, ", ")) -- 输出: 5, 4, 3, 1, 1
Ⅱ、按字符串长度排序
local words = {"apple", "banana", "cat", "dog", "elephant"}
table.sort(words, function(a, b)
return #a < #b -- 按长度升序
end)
print(table.concat(words, ", ")) -- 输出: cat, dog, apple, banana, elephant
(五)最大值
table.maxn 在 Lua5.2 之后该方法已经不存在了,我们可以自己定义了 table_maxn 方法来实现获取表中的最大值。
方法:table_maxn(table)
参数说明:
从table中返回一个最大的值
举例:
--自定义table_maxn()方法
function table_maxn(t)
local mn=nil
for k,v in pairs(t) do
if mn==nil then
mn=v
end
if mn<v then
mn=v
end
end
return mn
end
t={5,4,8,3,9,4,1,2.0}
print(table_maxn(t)) --输出:9
参考文档:
官方文档:Lua 5.4 参考手册 - 目录 - Lua 编程语言
参考文档:Lua table(表) | 菜鸟教程
更多推荐



所有评论(0)