Lua,自定义迭代器 - 定义的正确方式?
2017-9-1 18:58:26
收藏:0
阅读:90
评论:2
我正在处理很多以 Lua 编写的数据文件。其中大部分以这种方式编写,以“电话簿”为例:
data = {
-- 第一级 - 国家
美国 = {
-- 第二级 - 城市
丹佛 = {
-- 第三级 - 实际条目
{姓名 = '约翰', 号码 = '12345'},
-- 更多条目
},
华盛顿 = {
{姓名 = '安', 号码 = '54321'},
-- 更多条目
},
-- 具有条目的更多城市
},
-- 具有城市和条目的更多国家
}
因此,第一级是“国家”,第二级是“城市”,但这是隐式的,但它使数据更紧凑。
现在,当实际搜索某些数据时,我想按条目包括此级别,隐含信息迭代此数据。
-- 协程产生包括级别数据的条目
function corIter(data)
for country,l1 in pairs(data) do
for city,l2 in pairs(l1) do
for _,entry in pairs(l2) do
-- 复制条目
local out = {}
for k,v in pairs(entry) do
out[k] = v
end
-- 添加级别属性
out.country = country
out.city = city
coroutine.yield(out)
end
end
end
end
-- 迭代条目
local cor = coroutine.create(corIter)
local _, entry = coroutine.resume(cor, data)
while entry do
-- 处理条目,带有 'name'、'number'、'country' 和 'city' 键
table.print(entry) -- (我使用的自定义打印函数)
-- 获取下一个
_, entry = coroutine.resume(cor)
end
但我认为这种方法可能很糟糕,因为它只是为了以特定方式迭代一个该死的表而保持整个线程活动。
是否有任何其他“明显”的解决方案?关键在于性能和易用性。我不需要一个通用解决方案(针对数据表内任意数量的“级别”),但总体而言,这都像是一个 hack。
点赞
用户8528277
你可以在Lua中创建自己的自定义迭代器,无需使用协程。迭代器是函数,当被调用时,返回你的结构中的下一个元素(你可以使用任何结构)
针对你的示例,迭代器可能如下所示:
function corIter(data)
local itOut = {}
for country,l1 in pairs(data) do
for city,l2 in pairs(l1) do
for _,entry in pairs(l2) do
-- 拷贝条目
local out = {}
for k,v in pairs(entry) do
out[k] = v
end
out.country = country
out.city = city
table.insert(itOut,out)
end
end
end
local i = 0
return function()
i = i + 1
return itOut[i]
end
end
'corIter'返回的匿名函数将从你的数据中返回下一个元素。请注意,当我们使用'pairs'将条目复制到另一个表中进行迭代时,没有任何保证条目的顺序会保持原始顺序。
因此,现在您可以使用以下代码打印出条目:
for entry in corIter(data) do
print(entry) -- 这是一个表
for k,v in pairs(entry) do
print(k,v) -- 这些是实际值
end
end
2017-09-01 21:24:24
评论区的留言会收到邮件通知哦~
推荐文章
- Lua 虚拟机加密load(string.dump(function)) 后执行失败问题如何解决
- 我想创建一个 Nginx 规则,禁止访问
- 如何将两个不同的lua文件合成一个 东西有点长 大佬请耐心看完 我是小白研究几天了都没搞定
- 如何在roblox studio中1:1导入真实世界的地形?
- 求解,lua_resume的第二次调用继续执行协程问题。
- 【上海普陀区】内向猫网络招募【Skynet游戏框架Lua后端程序员】
- SF爱好求教:如何用lua实现游戏内调用数据库函数实现账号密码注册?
- Lua实现网站后台开发
- LUA错误显式返回,社区常见的规约是怎么样的
- lua5.3下载库失败
- 请问如何实现文本框内容和某个网页搜索框内容连接,并把网页输出来的结果反馈到另外一个文本框上
- lua lanes多线程使用
- 一个kv数据库
- openresty 有没有比较轻量的 docker 镜像
- 想问一下,有大佬用过luacurl吗
- 在Lua执行过程中使用Load函数出现问题
- 为什么 neovim 里没有显示一些特殊字符?
- Lua比较两个表的值(不考虑键的顺序)
- 有个lua简单的项目,外包,有意者加微信 liuheng600456详谈,最好在成都
- 如何在 Visual Studio 2022 中运行 Lua 代码?

local function phones(d) local cn, c, tn, t, i return function() local a repeat if tn then a, i = t[i], i+1 if not a then i, tn, t = 1, next(c, tn) end else cn, c = next(d, cn) i, tn, t = 1, next(c or {}) end until a or not cn return cn, tn, a end end -- 遍历 data 表中的电话信息 for country, town, abonent in phones(data) do print(country, town, abonent.name, abonent.number) end