我想将 2d lua 表转换为字符串,然后在将其转换为字符串后,使用新创建的字符串将其转换回表。似乎这个过程被称为序列化,并在下面的 url 中讨论,但我很难理解代码,希望这里有人有一个简单的 table.toString 和 table.fromString 函数
http://lua- users.org/wiki/TableSerialization
8 回答
我正在使用以下代码来序列化表:
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)()
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)
序列化的一般思想是从某个数据结构(如表)中获取所有数据位,然后在该数据结构中循环,同时构建一个字符串,该字符串包含所有这些数据位以及格式化字符。
JSON 模块怎么样?这样你也有更好的可交换数据。我通常更喜欢 dkjson,它也支持 utf-8,而 cmjjson 不支持。
在香港工作这个
local cjson = require "cjson"
kong.log.debug(cjson.encode(some_table))
出kong应该安装包lua-cjson https://github.com/openresty/lua-cjson/
这是一个简单的程序,它假设您的表格仅包含数字。它输出的 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"}"
假如说:
- 您没有循环(表 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
将更加复杂。
问候!
我有更短的代码将表格转换为字符串但不反转
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可执行文件,如果你输入新行和“序列,它将产生编译错误,这种方法更节省内存
笔记:
- 不支持的功能
- 我不知道的用户数据
我的解决方案:
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)