leevis.com
leevis.com copied to clipboard
lua 迭代器与泛型for
迭代器(iterator)是一种数据结构,能够遍历集合的每个元素。在lua中是一种支持指针类型的结构。
lua中熟知的迭代器有pairs和ipairs。通常配合泛型for同时使用。
例如:
a = {3, 1, 12}
for i, v in ipairs(a) do
print(i, v)
end
我们自己也可以实现一个类似于ipairs的功能
function iter (a, i)
i = i + 1
local v = a[i]
if v then
return i, v
end
end
function myipairs (a)
return iter, a, 0
end
使用自定义的迭代器也可以实现类似ipairs的功能
for i, v in myipairs(a) do
print(i,v)
end
通过自定义的迭代器函数可以看出是泛型for在自己内部保存迭代函数,实际上它保存三个值:迭代函数、状态常量、控制变量。
- 范性for的执行过程:
- 首先,初始化,计算
in后面表达式的值,表达式应该返回范性for需要的三个值:迭代函数、状态常量、控制变量;与多值赋值一样,如果表达式返回的结果个数不足三个会自动用nil补足,多出部分会被忽略。 - 第二,将状态常量和控制变量作为参数调用迭代函数(注意:对于for结构来说,状态常量没有用处,仅仅在初始化时获取他的值并传递给迭代函数)。
- 第三,将迭代函数返回的值赋给变量列表。
- 第四,如果返回的第一个值为nil循环结束,否则执行循环体。
- 第五,回到第二步再次调用迭代函数。
- 首先,初始化,计算
:loudspeaker: 注: 第二步是真正for循环的开始。第一步只是准备(如果理解了闭包,其实就是调用返回闭包)。迭代器返回的就是控制变量和控制变量对应的值,把上述自定义函数修改一下可能更容易理解。
function iter (a, i)
local v = a[I+1]
if v then
return i+1, v
end
end
自定义pairs迭代器:
function mypairs(a)
return next, a, nil
end
自定义限制循环中增加table元素的迭代器
function xpairs(a)
local size = table.maxn(a)
local function iter(a, k)
local t = table.maxn(a)
if t > size then
return
end
return next(a, k)
end
return iter, a, nil
end
--例如
local xx = {1, 2, 3, 4}
for k, v in xpairs(xx) do
print(k, v)
-- xx[#xx+1] = v+4
end
自定义限制循环次数的迭代器
function xpairs(a)
local size = table.maxn(a)
if size > 32 or size == 0 then
size = 32
end
local t = 0
local function iter(a, k)
t = t + 1
if t > size then
return
end
return next(a, k)
end
return iter, a, nil
end