Lua:检查表是否可以通过从0开始的ipairs循环遍历
2014-12-28 9:48:13
收藏:0
阅读:118
评论:2
我有一个很好的 Lua 表解析器,能打印出漂亮的 Lua 代码,而且我很喜欢它......它运行得很好。但是有一个小问题......如果我要打印具有任何整数键的表或数组,它将使用 pairs(具有讽刺意味的是,它不会破坏代码),但我宁愿它使用 ipairs。所以,我想知道,有没有可能检查一张表(不用看它)是否可以首先使用 ipairs 循环遍历它,否则使用 pairs。然后,有没有一种方法可以从 0 开始循环,而不是 Lua 的默认值 1?
Lua 表解析器(在谷歌上找到的基础代码,我改变了它使它更适合打印数组)...
function TableParser(name, object, tabs)
local function serializeKeyForTable(k)
if type(k)=="number" then
return ""
end
if string.find(k,"[^A-z_-]") then
return k
end
return k
end
local function serializeKey(k)
if type(k)=="number" then
if k == 0 then
return "\t[" .. k .."] = "
else
return "\t"
end
end
if string.find(k,"[^A-z_-]") then
return "\t" .. k .. " = "
end
return "\t" .. k .. " = "
end
if not tabs then tabs = "" end
local function serialize(name, object, tabs) -- = {
local output = tabs .. (name ~= "" and name .. " = " or "") .. "{" .. "\n"
for k,v in pairs(object) do
if type(v) == "number" then
output = output .. tabs .. serializeKey(k) .. v
elseif type(v) == "string" then
output = output .. tabs .. serializeKey(k) .. string.format("%q",v)
elseif type(v) == "table" then
output = output .. serialize(serializeKeyForTable(k), v, tabs.."\t")
elseif type(v) == "boolean" then
output = output .. tabs .. serializeKey(k) .. tostring(v)
else
output = output .. tabs .. serializeKey(k) .. "\"" .. tostring(v) .. "\""
end
if next(object,k) then
output = output .. ",\n"
end
end
return output .. "\n" .. tabs .. "}"
end
return serialize(name, object, tabs)
end
点赞
用户3204551
你总是可以使用 pairs 和 ipairs 遍历表格,无论是否有意义。
ipairs遍历表格中存在的序列(指以 1 开始的连续整数键,直到第一个缺失的值),除非被元方法__ipairs(5.2)覆盖。pairs使用next遍历表格中所有键值对(因此顺序不确定),除非被元方法__pairs(5.2)覆盖。
这意味着 ipairs 通常不会枚举 pairs 不显示的键值对。
而且没有办法验证 ipairs 是否会枚举所有 pairs 枚举的键,只能全部枚举并手动测试。
顺便说一下:你可以创建自己的迭代器,首先遍历序列,然后遍历其他所有键值对:
function my_iter(t)
local k, cap
return function()
local v
if k == nil then k, cap = 0 end
if not cap then
k = k + 1
v = t[k]
if v ~= nil then return k, v end
cap, k = k
end
repeat k, v = next(k)
until type(k) ~= "number" or 0 < k and k < cap and math.ceil(k) == k
return k, v
end
end
不过最好还是排序键以获得美观的输出:
function sorted_iter(t)
local keys, index = {}, 0
for k in next, t do
keys[#keys + 1] = k
end
table.sort(keys)
return function()
index = index + 1
local k = keys[index]
return k, t[k]
end
end
2014-12-28 11:05:51
评论区的留言会收到邮件通知哦~
推荐文章
- 如何将两个不同的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 代码?
- addEventListener 返回 nil Lua
- Lua中获取用户配置主目录的跨平台方法
所以我想知道是否可以检查一个表格(不用实际去查看它),如果可以使用
ipairs对其进行循环,否则使用pairs。不要检查,直接使用!首先使用
ipairs并跟踪ipairs迭代器返回的最大键。然后再次使用pairs进行迭代,并忽略1和从ipairs中获取的最大键之间的所有整数键。如果你真的想要检查
ipairs是否会做任何事情,那么请查看表格中的索引1(rawget(object,1)~=nil)。在不迭代表格的情况下,不可能检查ipairs是否将覆盖表格中的所有元素。接下来可能会有问题:有没有办法从0开始循环,而不是默认的Lua 1?
ipairs(t)返回三个值:一个迭代器函数,表格t作为状态变量和初始索引值0。如果你将-1作为初始索引值,则ipairs将从0开始迭代(迭代器函数总是在使用索引值之前递增一):t = { 1, 2, 3, [0] = 0 } for i,v in ipairs( t ), t, -1 do -- 仅使用ipairs返回的第一个值 print( i, v ) end然而,请注意,Lua 5.2已经添加了对一个新的元方法
__ipairs的支持,它允许你返回一个自定义的迭代器三元组来用于ipairs迭代,并且在这种情况下返回的迭代器函数可能需要不同的状态和初始索引值。编辑: 要将建议结合到你的代码中,请在
for k,v in pairs(object) do循环之前插入:local largest = 0 for k,v in ipairs(object) do largest = k local t = type(v) if t == "table" then output = output .. tabs .. "\t" .. serialize( "", v, tabs.."\t" ) elseif t == "string" then output = output .. tabs .. "\t" .. string.format("%q", v) else output = output .. tabs .. "\t" .. tostring(v) end output = output .. ",\n" end并且在循环内部添加额外的
if语句以检查数组键:for k,v in pairs(object) do if type(k) ~= "number" or k < 1 or k > largest or math.floor(k) ~= k then -- if type(v) == "number" then -- ... end end如果你将修改后的
TableParser函数应用于以下表格:local t = { 1, 2, 3, value = "x", tab = { "a", "b", field = "y" } } print( TableParser( "", t ) )则输出为:
{ 1, 2, 3, tab = { "a", "b", field = "y" }, value = "x" }但是正确地处理表格序列化是棘手的。例如,你的实现未处理循环或表格作为键。请参见Lua Wiki以获取一些实现。