6

我想将 2d lua 表转换为字符串,然后在将其转换为字符串后,使用新创建的字符串将其转换回表。似乎这个过程被称为序列化,并在下面的 url 中讨论,但我很难理解代码,希望这里有人有一个简单的 table.toString 和 table.fromString 函数
http://lua- users.org/wiki/TableSerialization

4

8 回答 8

17

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

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-21T12:14:07.507 回答
9

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-20T17:57:58.303 回答
7

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

于 2011-05-21T00:30:25.250 回答
3

在香港工作这个

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

出kong应该安装包lua-cjson https://github.com/openresty/lua-cjson/

于 2020-05-19T06:26:01.700 回答
2

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

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

print"return {"
for i=1,#t do
        print"{"
        for j=1,#t[i] do
                print(t[i][j],",")
        end
        print"},"
end
print"}"
于 2011-05-20T17:47:56.373 回答
2

假如说:

  • 您没有循环(表 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-21T08:06:25.470 回答
1

我有更短的代码将表格转换为字符串但不反转

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-01T11:50:21.250 回答
1

我的解决方案:

local nl = string.char(10) -- newline
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 ""
        if type (value) == "table" then
            str = str..nl..pr..serialize_list (value, indent)..','
        elseif type (value) == "string" then
            str = str..nl..indent..pr..'"'..tostring(value)..'",'
        else
            str = str..nl..indent..pr..tostring(value)..','
        end
    end
    str = str:sub(1, #str-1) -- remove last symbol
    str = str..nl..indent.."}"
    return str
end

local str = serialize_list(tables)
print('return '..nl..str)
于 2021-01-08T15:44:07.807 回答