樹形打印lua table表

爲方便調試lua程序,每每想以樹的形式打印出一個table,以觀其表內數據。如下羅列了三種種關於樹形打印lua table的方法;
法一
local print = print
local tconcat = table.concat
local tinsert = table.insert
local srep = string.rep
local type = type
local pairs = pairs
local tostring = tostring
local next = next

function print_lua_table (lua_table, indent)

    if not lua_table or type(lua_table) ~= "table" then
        return;
    end

    indent = indent or 0
    for k, v in pairs(lua_table) do
        if type(k) == "string" then
            k = string.format("%q", k)
        end
        local szSuffix = ""
        if type(v) == "table" then
            szSuffix = "{"
        end
        local szPrefix = string.rep("    ", indent)
        formatting = szPrefix.."["..k.."]".." = "..szSuffix
        if type(v) == "table" then
            print(formatting)
            print_lua_table(v, indent + 1)
            print(szPrefix.."},")
        else
            local szValue = ""
            if type(v) == "string" then
                szValue = string.format("%q", v)
            else
                szValue = tostring(v)
            end
            print(formatting..szValue..",")
        end
    end
end
  以上是一個樹形打印lua table 【原方法的連接】的基本源碼,雖是參考雲風的方法而來,卻 不可以支持表內循環(打印出來的樣子仍是挺符合 通常人的內心預期的);

法二 lua

       譬如一下這個例子: 由於表內引用了自身形成循環引用,因此打印方法也就成了 死循環了;spa

a = {}
a.a = {
    hello = {
        alpha = 1 ,
        beta = 2,
    },
    world =  {
        foo = "ooxx",
        bar = "haha",
        root = a,
    },
}
a.b = {
    test = a.a
}
a.c = a.a.hello

下面是 雲風大神 關於lua table樹形打印的源碼連接;調試

local print = print
local tconcat = table.concat
local tinsert = table.insert
local srep = string.rep
local type = type
local pairs = pairs
local tostring = tostring
local next = next
 
function print_r(root)
    local cache = {  [root] = "." }
    local function _dump(t,space,name)
        local temp = {}
        for k,v in pairs(t) do
            local key = tostring(k)
            if cache[v] then
                tinsert(temp,"+" .. key .. " {" .. cache[v].."}")
            elseif type(v) == "table" then
                local new_key = name .. "." .. key
                cache[v] = new_key
                tinsert(temp,"+" .. key .. _dump(v,space .. (next(t,k) and "|" or " " ).. srep(" ",#key),new_key))
            else
                tinsert(temp,"+" .. key .. " [" .. tostring(v).."]")
            end
        end
        return tconcat(temp,"\n"..space)
    end
    print(_dump(root, "",""))
end

那麼打印出來的效果是這樣: code

+a+hello+alpha [1]
| |     +beta [2]
| +world+root {.}
|       +bar [haha]
|       +foo [ooxx]
+c {.a.hello}
+b+test {.a}

上面的方法,若是摒除去 root = a 這項元素的循環引用,可打印出來的樣子是這樣的:orm

["a"] = {
    ["hello"] = {
        ["alpha"] = 1,
        ["beta"] = 2,
    },
    ["world"] = {
        ["bar"] = "haha",
        ["foo"] = "ooxx",
    },
},
["c"] = {
    ["alpha"] = 1,
    ["beta"] = 2,
},
["b"] = {
    ["test"] = {
        ["hello"] = {
            ["alpha"] = 1,
            ["beta"] = 2,
        },
        ["world"] = {
            ["bar"] = "haha",
            ["foo"] = "ooxx",
        },
    },
},["a"] = {
    ["hello"] = {
        ["alpha"] = 1,
        ["beta"] = 2,
    },
    ["world"] = {
        ["bar"] = "haha",
        ["foo"] = "ooxx",
    },
},
["c"] = {
    ["alpha"] = 1,
    ["beta"] = 2,
},
["b"] = {
    ["test"] = {
        ["hello"] = {
            ["alpha"] = 1,
            ["beta"] = 2,
        },
        ["world"] = {
            ["bar"] = "haha",
            ["foo"] = "ooxx",
        },
    },
},

 法三:blog

也能夠利用lua的序列化將lua錶轉化爲string,再將其給print出來;get

-- 序列化tablle表--將表轉化成string
function serialize(obj)
    local lua = ""
    local t = type(obj)
    if t == "number" then
        lua = lua .. obj
    elseif t == "boolean" then
        lua = lua .. tostring(obj)
    elseif t == "string" then
        lua = lua .. string.format("%q", obj)
    elseif t == "table" then
        lua = lua .. "{\n"
    for k, v in pairs(obj) do
        lua = lua .. "[" .. serialize(k) .. "]=" .. serialize(v) .. ",\n"
    end
    local metatable = getmetatable(obj)
        if metatable ~= nil and type(metatable.__index) == "table" then
        for k, v in pairs(metatable.__index) do
            lua = lua .. "[" .. serialize(k) .. "]=" .. serialize(v) .. ",\n"
        end
    end
        lua = lua .. "}"
    elseif t == "nil" then
        return nil
    else
        return "-nil-" 
        --error("can not serialize a " .. t .. " type.")
    end
    return lua
end

下面附上 lua的反序列化方法(即 將string[內容是lua table]再轉會lua table)源碼

-- 反序列化tablle表--將string轉化成table
function unserialize(lua)
    local t = type(lua)
    if t == "nil" or lua == "" then
        return nil
    elseif t == "number" or t == "string" or t == "boolean" then
        lua = tostring(lua)
    else
        error("can not unserialize a " .. t .. " type.")
    end
    lua = "return " .. lua
    local func = loadstring(lua)
    if func == nil then
        return nil
    end
    return func()
end
相關文章
相關標籤/搜索