2011-05-20 35 views

回答

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) 

系列化的總體思路是把數據的所有位從一些數據結構像一個表,然後遍歷數據結構,而建立一個包含所有這些數據位以及格式化字符的字符串。

+0

感謝您的代碼。我的意思是重新定義'print'或使用不同的函數來收集表格中的輸出,以便可以保持原始代碼基本完好無損。 – lhf 2011-05-20 18:32:55

+1

我討厭重載函數,因爲我總是忘記我改變了它。 – jhocking 2011-05-20 18:52:24

+1

我相信'#t'必須做一些迭代來計算表的長度。使用自己的長度計數器變量可能更有效。 – Ponkadoodle 2011-05-22 18:32:49

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

JSON module怎麼樣?這樣你也可以獲得更好的可交換數據。我通常更喜歡dkjson,它也支持utf-8,其中cmjjson不會。

+0

Upvote讓我意識到JSON是更好的解決方案。我已經擁有*我在項目中使用過的JSON庫,甚至,但我忘記了。 – SomeCallMeTim 2016-03-29 18:06:41

+0

從技術上講,這並不能回答這個問題,但使用JSON可能比數據序列化更好。 – jhocking 2016-07-08 19:36:21

1

假設:

  • 您沒有循環(表引用表B和B引用)
  • 你的表是純陣列(所有鍵都是連續的正整數,開始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將更復雜 。

問候!

7

以序列表我使用下面的代碼:

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 

創建的代碼,然後可以使用加載鏈()執行: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

你知道,tostring也適用於布爾值。 tostring(true)==「true」 – Ponkadoodle 2011-05-22 18:34:38

+0

修改了一下並使用了它。謝謝 :) – 2018-01-11 11:08:16