Lua表格.toString(tableName)和表格.fromString(stringTable)函数?

我想将一个2D Lua表格转换成字符串,然后再将其转换回一个新创建的字符串使用的表格。这个过程似乎被称为序列化,并且在下面的URL中进行讨论,但我很难理解代码,希望这里有人有一个简单的table.toString和table.fromString函数。

http://lua-users.org/wiki/TableSerialization

原文链接 https://stackoverflow.com/questions/6075262

点赞
stackoverflow用户107090
stackoverflow用户107090

以下是一个简单的程序,它假设您的表只包含数字。它输出的 Lua 代码可以通过 loadstring()() 加载回来。将其调整为输出到字符串而不是打印。提示:重新定义 print 以将输出收集到表中,然后在最后使用 table.concat 将输出表转换为字符串。

t = {
{11,12,13},
{21,22,23},
}

local output = {}
table.insert(output, "return {")
for i=1,#t do
        table.insert(output, "{")
        for j=1,#t[i] do
                table.insert(output, t[i][j]..",")
        end
        table.insert(output, "},")
end
table.insert(output, "}")

local output_str = table.concat(output, "\n")
2011-05-20 17:47:56
stackoverflow用户686008
stackoverflow用户686008
lhf 发布的代码示例比你链接的页面中的任何代码都简单,希望你能更好地理解它。将其调整为输出字符串而不是打印输出的代码如下:

t = { {11,12,13}, {21,22,23}, }

local s = {"return {"} for i=1,#t do s[#s+1] = "{" for j=1,#t[i] do s[#s+1] = t[i][j] s[#s+1] = "," end s[#s+1] = "}," end s[#s+1] = "}" s = table.concat(s)

print(s)

```

序列化的一般思想是从诸如表格之类的数据结构中获取所有数据位,然后循环遍历该数据结构,同时建立一个字符串,其中包含所有这些数据位以及格式化字符。

2011-05-20 17:57:58
stackoverflow用户457630
stackoverflow用户457630

怎么样使用 JSON 模块?这样你也会有一个更好的可交换数据方式。我通常更喜欢 dkjson,它也支持 utf-8,而 cmjjson 不支持。

2011-05-21 00:30:25
stackoverflow用户312586
stackoverflow用户312586

假设:

  • 没有循环引用(表 a 引用表 b,表 b 同时引用表 a)
  • 表格是纯数组(所有键都是连续的正整数,从 1 开始)
  • 值仅为整数(无字符串等内容)

那么,递归解决方案易于实现:

function serialize(t)
  local serializedValues={}
  local value,serializedValue
  for i=1,#t do
    value=t[i]
    serializedValue=type(value)=='table' and serialize(value) or value
    table.insert(serializedValues,serializedValue)
  end
  return string.format("{ %s }",table.concat(serializedValues,', ') )
end

在这个函数的结果前面加上一个 return,并将其存储在一个 .lua 文件中:

-- myfile.lua
return { { 1, 2, 3 }, { 4, 5, 6 } }

您只需使用 dofile 就可以重新获取到该表。

t = dofile 'myfile.lua'

注:

  • 如果存在循环引用,则必须显式处理它们-通常需要使用额外的表来“跟踪”重复项
  • 如果没有纯数组,那么必须以不同的方式解析 t,以及处理键的渲染方式(它们是字符串吗?它们是其他表吗?等等)。
  • 如果不仅有整数和子表,那么计算 serializedValue 将变得更加复杂。

此致!

2011-05-21 08:06:25
stackoverflow用户570336
stackoverflow用户570336

我正在使用以下代码来序列化表格:

function serializeTable(val, name, skipnewlines, depth)
    skipnewlines = skipnewlines or false
    depth = depth or 0

    local tmp = string.rep(" ", depth)

    if name then tmp = tmp .. name .. " = " end

    if type(val) == "table" then
        tmp = tmp .. "{" .. (not skipnewlines and "\n" or "")

        for k, v in pairs(val) do
            tmp =  tmp .. serializeTable(v, k, skipnewlines, depth + 1) .. "," .. (not skipnewlines and "\n" or "")
        end

        tmp = tmp .. string.rep(" ", depth) .. "}"
    elseif type(val) == "number" then
        tmp = tmp .. tostring(val)
    elseif type(val) == "string" then
        tmp = tmp .. string.format("%q", val)
    elseif type(val) == "boolean" then
        tmp = tmp .. (val and "true" or "false")
    else
        tmp = tmp .. "\"[inserializeable datatype:" .. type(val) .. "]\""
    end

    return tmp
end

然后使用 loadstring() 来执行代码:http://www.lua.org/manual/5.1/manual.html#pdf-loadstring,如果你传递了一个参数给 'name' 参数(或者之后追加):

s = serializeTable({a = "foo", b = {c = 123, d = "foo"}})
print(s)
a = loadstring(s)()
2011-05-21 12:14:07
stackoverflow用户13447666
stackoverflow用户13447666

将表格转换为字符串的代码

我有一个更短的代码可以将表格转换为字符串,但不能反向操作。

function compileTable(table)
   local index = 1
   local holder = "{"
   while true do
      if type(table[index]) == "function" then
         index = index + 1
      elseif type(table[index]) == "table" then
         holder = holder..compileTable(table[index])
      elseif type(table[index]) == "number" then
         holder = holder..tostring(table[index])
      elseif type(table[index]) == "string" then
         holder = holder.."\""..table[index].."\""
      elseif table[index] == nil then
         holder = holder.."nil"
      elseif type(table[index]) == "boolean" then
         holder = holder..(table[index] and "true" or "false")
      end
      if index + 1 > #table then
        break
      end
      holder = holder..","
      index = index + 1
   end
   return holder.."}"
end

如果你想更改名称,只需搜索所有 compileTable 并将其更改为你喜欢的名称,因为这个函数将在检测到嵌套表时调用自己,但转义序列我不知道是否有效。

如果你使用这个来创建一个 Lua 可执行文件输出表格,那么如果你输入换行符和 “ 序列,它将得到编译错误。这种方法的内存效率更高。

注:

  1. 不支持函数。
  2. 我不知道用户数据。
2020-05-01 11:50:21
stackoverflow用户3440890
stackoverflow用户3440890

在 Kong 中运行如下代码:

local cjson = require "cjson"
kong.log.debug(cjson.encode(some_table))

需要安装 lua-cjson 包 https://github.com/openresty/lua-cjson/

2020-05-19 06:26:01
stackoverflow用户12968803
stackoverflow用户12968803

我的解决方案:

local nl = string.char(10) -- 换行符
function serialize_list (tabl, indent)
    indent = indent and (indent.."  ") or "" -- 缩进
    local str = ''
    str = str .. indent.."{"
    for key, value in pairs (tabl) do
        local pr = (type(key)=="string") and ('["'..key..'"]=') or "" -- 确定 key 的格式
        if type (value) == "table" then -- 如果 value 是表则递归
            str = str..nl..pr..serialize_list (value, indent)..','
        elseif type (value) == "string" then -- 如果 value 是字符串则添加引号
            str = str..nl..indent..pr..'"'..tostring(value)..'",'
        else -- 其他情况直接添加
            str = str..nl..indent..pr..tostring(value)..','
        end
    end
    str = str:sub(1, #str-1) -- 移除最后一个字符(逗号)
    str = str..nl..indent.."}"
    return str
end

local str = serialize_list(tables)
print('return '..nl..str)
2021-01-08 15:44:07