parsing - Lua:检查表是否可以通过 ipairs & ipairs 从 0 开始循环

标签 parsing lua integer lua-table

我有一个漂亮的小 Lua 表解析器,它打印出看起来很漂亮的 lua 代码,我喜欢它……它工作得很好。有一个小问题...如果我要打印一个表或数组,它有任何整数键,它使用 pairs 循环遍历它。 (讽刺的是,这不会弄乱代码),但我宁愿它使用 ipairs如果可能的话。所以我想知道是否可以检查表(无需物理查看它)是否可以使用 ipairs 首先循环遍历它,否则使用对。那么有没有办法从 0 而不是 Lua 的默认 1 开始循环?

Lua 表解析器(在 google 上找到的基本代码,对其进行了更改以使其打印更友好的数组)...

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

最佳答案

So I want to know is it possible to check a table (without physically looking at it) if it can use ipairs to loop through it first else use pairs.



不检查,做!使用 ipairs首先跟踪最大的 key ipairs迭代器返回。然后使用 pairs再次迭代并忽略 1 之间的所有整数键以及来自 ipairs 的最大 key .

如果真的要检查是否ipairs会做点什么,然后看索引1在表中 ( rawget( object, 1 ) ~= nil )。检查是否ipairs如果不迭代表,就不可能覆盖表中的所有元素。

Then is there a way to start looping at 0 instead of Lua's default 1?


ipairs(t)返回三个值:一个迭代器函数,表 t作为状态变量,以及初始索引值 0 .如果您使用 -1作为初始索引值,ipairs将在 0 开始迭代(迭代器函数在使用索引值之前总是加一):
t = { 1, 2, 3, [ 0 ] = 0 }
for i,v in ipairs( t ), t, -1 do  -- only use first value returned by 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对于某些实现。

关于parsing - Lua:检查表是否可以通过 ipairs & ipairs 从 0 开始循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27674367/

相关文章:

php - 从 DB 提取到 XML

mysql - switch 语句内的奇怪结果

string - Lua - 得到所有的单词

c - Lua: "Hide"函数

java - 600851475143 的 "Integer number too large"错误消息

ios - 无法使用 Swift Decodable 解析 JSON

c++ - 未调用 boost spirit 语义 Action

mysql-proxy 结果字段操作

algorithm - 完美平方算法 - 实现说明

c++ - 为什么我的变量在我设置它们的类之外打印时给出不同的值?