我们继续来学一些东西
多维数组
数组这东西咱们之前其实已经学过了,基本上没什么说的了,因为lua里面数组字典都是一个东西
但是有一个东西不得不提那就是table的数组的一面的多维数组性
说人话就是和其他语言一样,lua的数组也可以嵌套,而且用法一模一样
二维数组
LUA已复制
local matrix = {
{ 1, 2, 3 },
{ 4, 5, 6 },
{ 7, 8, 9 }
}
print(matrix[1][1]) -- 1
print(matrix[2][3]) -- 6
print(matrix[3][2]) -- 8
for i = 1, #matrix do
for j = 1, #matrix[i] do
io.write(matrix[i][j], " ")
end
print()
end

三维数组
LUA已复制
local cube = {
{
{ 1, 2 },
{ 3, 4 }
},
{
{ 5, 6 },
{ 7, 8 }
}
}
for i = 1, #cube do
print("layer", i)
for j = 1, #cube[i] do
for k = 1, #cube[i][j] do
io.write(cube[i][j][k], " ")
end
print()
end
print()
end

递归遍历数组
因为手动敲代码非常麻烦,而且每增加一层数组就要套上一个for循环,所以我们采用递归遍历,实现一劳永逸
LUA已复制
--t 当前遍历的 table
--callback 处理数据的函数
--path 记录当前坐标(路径)
local function walkArray(t, callback, path)
--如果没有 path 就创建一个空表
path = path or {}
--pairs用于遍历表
--k 表示当前元素的索引(key),从1开始
--v 表示当前元素的值(value)
for k, v in pairs(t) do
--例如:
--最开始 path = {}
--#path = 0
--所以 path[#path+1] = path[1] = k
--如果当前k=1
--那么 path 就变成 {1}
path[#path + 1] = k
--这里可以这样理解:
--假设我们把 cube 当成一个洋葱
--我们一层一层往里面拨
--第一层
--cube里面的元素其实是两个table
--第二层
--里面的元素还是table
--第三层
--才是最终的数字
--所以程序每次都会检查
--当前元素是不是table
if type(v) == "table" then
--如果还是table
--说明还没有拨到最里面
--于是继续把这个table塞进walkArray函数
--继续往里面遍历
--注意:
--这里的path不是新的table
--而是同一个path在不断增加路径
walkArray(v, callback, path)
else
--如果不是table
--说明已经到达最底层元素
--此时就执行callback函数
--callback会收到两个参数
--value = 当前值
--path = 当前值的路径
callback(v, path)
end
--这一行非常关键
--path[#path] = nil 的作用是删除最后一个路径
--例如:
--path = {1,2,3}
--删除后变成
--path = {1,2}
--这样程序就可以回到上一层继续遍历
--否则path会越来越长
path[#path] = nil
end
end
--三维数组
local cube = {
--第一层
{
--第二层
{
--第三层
1,
2,
3
},
{
--第三层
4,
5,
6
}
},
{
--第二层
{
--第三层
7,
8,
9
},
{
--第三层
10,
11,
12
}
}
}
--调用函数
walkArray(cube,
--匿名函数(也叫回调函数)
--当walkArray找到一个最终的值时
--就会执行这个函数
function(value, path)
--打印 index
io.write("index ")
--path里面存的是当前元素的完整路径
--例如 {1,2,3}
--表示 cube[1][2][3]
for i = 1, #path do
io.write("[" .. path[i] .. "]")
end
--打印值
print(" = " .. value)
end
)

你别说,我真的看不懂这写的什么意思,我以前从来没有认真看过递归(因为用不上我也从来不看这个),现在理解起来还是有点困难的
迭代器
迭代器包括泛型 for 迭代器,无状态的迭代器,多状态的迭代器
其中泛型 for 迭代器我们已经学过了,我们就不说了,这个就是我们前面说的遍历表的ipairs和pairs这些东西
泛型 for 迭代器
语法为
LUA已复制
for var_1, var_2 in iterator_func, state, init do
-- 循环体
end
| 泛型 for 部分 | 作用 | 具体值 |
|---|---|---|
iterator_func |
每次迭代被调用的函数(返回下一个值) | square |
state |
迭代器固定数据(不会变的东西) | 3 (最大迭代次数) |
init |
迭代器固定数据(不会变的东西) | 0 (控制变量初始值) |
var_1, var_2 |
循环体变量,用来接收迭代器返回值 | i, n(循环体变量) |
例如
LUA已复制
array = {"Google", "Runoob"}
for key,value in ipairs(array)
do
print(key, value)
end
--Google
--Runoob
-
| 函数 | 类型 | 功能 |
|---|---|---|
ipairs(t) |
无状态 | 按索引顺序遍历数组部分 |
pairs(t) |
多状态 | 遍历表中所有键值对 |
string.gmatch(s, pattern) |
多状态 | 按模式匹配字符串 |
io.lines(filename) |
多状态 | 按行读取文件 |
无状态的迭代器(stateless iterator)
无状态:迭代函数本身不保存任何内部状态,它只依赖两个输入:
- 状态常量(通常是固定的数据集合,比如表)
- 控制变量(循环中表示当前位置的索引或计数器)
循环机制:每一次迭代,Lua 都调用迭代函数
f(state, control),由迭代函数返回下一个元素优势:不需要闭包开销,效率高,适合简单、固定的序列遍历
LUA已复制
-- 无状态迭代器
local function iter(n, i)
i = i + 1
if i <= n then
return i
end
end
local n = 5
for i in iter, n, 0 do
print(i)
end
--1
--2
--3
--4
--5
解析:
iter 是迭代器函数,每次被调用时接收两个参数:
n(state)
i(上一次返回的值,初始是 0)
返回下一个值,直到返回 nil 时循环结束
特点:迭代器本身不记状态,状态由循环外部传递进来
LUA已复制
function square(iteratorMaxCount, currentNumber)
if currentNumber < iteratorMaxCount then
currentNumber = currentNumber + 1
return currentNumber, currentNumber * currentNumber
end
end
for i, n in square, 3, 0 do
print(i, n)
end
--1 1
--2 4
--3 9
解析:
迭代函数:square(iteratorMaxCount, currentNumber)
每次被调用,传入状态常量 iteratorMaxCount(最大迭代次数)和控制变量 currentNumber(上一次返回的值)
返回值:返回下一个索引和它的平方
Lua 的 for 循环会不断调用 square,直到返回 nil 停止
多状态的迭代器(stateful iterator)
多状态:迭代器需要维护多个状态,可能包括:
- 当前索引
- 集合长度
- 缓存数据
实现方式:
- 闭包:迭代函数内保存状态变量。
- 表封装状态:状态信息放在 table 中,迭代函数每次读取。
特点:迭代器自己记住状态,循环不必每次传入控制变量。
LUA已复制
local function next_pair(t)
local key = nil
return function()
key = next(t, key)
if key then
return key, t[key]
end
end
end
local t = {a=1, b=2, c=3}
for k, v in next_pair(t) do
print(k, v)
end
--a 1
--b 2
--c 3
解析:
next_pair(t) 返回一个闭包函数,这个闭包保存了内部状态(key)。
每次调用闭包,都会从表中取下一个键值对。
循环结束条件是闭包返回 nil。
特点:迭代器自己保存状态,外部循环无需传递状态。
LUA已复制
local array = {"Google", "Runoob"}
function elementIterator(collection)
local index = 0
local count = #collection
-- 闭包函数,保存状态
return function()
index = index + 1
if index <= count then
return collection[index]
end
end
end
for element in elementIterator(array) do
print(element)
end
--Google
--Runoob


评论区