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

时间:2011-05-20 16:59:10

标签: serialization lua lua-table

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

8 个答案:

答案 0 :(得分:9)

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

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

如果您已经将参数传递给'name'参数(或者之后追加),则可以使用loadstring():http://www.lua.org/manual/5.1/manual.html#pdf-loadstring执行创建的代码:

s = serializeTable({a = "foo", b = {c = 123, d = "foo"}})
print(s)
a = loadstring(s)()

答案 1 :(得分:7)

发布的代码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)

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

答案 2 :(得分:4)

JSON module怎么样?这样你就拥有了更好的可交换数据。我通常更喜欢dkjson,它也支持utf-8,其中cmjjson不会。

答案 3 :(得分:2)

这是一个简单的程序,假设您的表只包含数字。它输出可以用loadstring()()加载的Lua代码。调整它以输出到字符串而不是打印出来。提示:重新定义打印以将输出收集到表中,然后在最后将输出表转换为带有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"}"

答案 4 :(得分:1)

假设:

  • 您没有循环(表格引用表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'

注意:

  • 如果你有循环,那么你将拥有 明确地处理它们 - 通常用一个额外的表来“跟踪”重复
  • 如果您没有纯数组,那么 你将不得不以不同的方式解析 以及处理键的呈现方式(它们是字符串吗?是其他表吗?等)。
  • 如果你不仅仅是整数 和子表,然后计算 serializedValue会更多 复杂。

问候!

答案 5 :(得分:1)

在香港工作下

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

应该在香港以外的地方安装软件包lua-cjson https://github.com/openresty/lua-cjson/

答案 6 :(得分: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)

答案 7 :(得分:0)

我有较短的代码可以将表转换为字符串,但不能反向

Traceback (most recent call last):
  File "/usr/lib/python3.7/threading.py", line 917, in _bootstrap_inner
    self.run()
  File "/usr/lib/python3.7/threading.py", line 865, in run
    self._target(*self._args, **self._kwargs)
  File "/home/pi/KEX/PKE_key_0.5/bt_rssi.py", line 101, in bluetooth_listen
    rssi = b.request_rssi()
  File "/home/pi/KEX/PKE_key_0.5/bt_rssi.py", line 63, in request_rssi
    bt.OCF_READ_RSSI, bt.EVT_CMD_COMPLETE, 4, self.cmd_pkt)
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xff in position 3: invalid start byte

如果要更改名称,只需搜索所有compileTable即可将其更改为您的首选名称,因为如果此功能检测到嵌套表但转义序列不知道它是否起作用,则该函数将自行调用

如果您使用此命令创建一个lua可执行文件来输出表,则在放置新行和序列时会产生ge编译错误 这种方法可以提高内存效率

注意:

  1. 不支持的功能
  2. 我不知道的用户数据