• 树形打印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 【原方法的链接】的基本源码,虽是参考云风的方法而来,却 不能够支持表内循环(打印出来的样子还是挺符合 一般人的心里预期的);

    法二 

           譬如一下这个例子: 因为表内引用了自身造成循环引用,所以打印方法也就成了 死循环了;

    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,"
    "..space)
        end
        print(_dump(root, "",""))
    end

    那么打印出来的效果是这样: 

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

    上面的方法,如果摒除去 root = a 这项元素的循环引用,可打印出来的样子是这样的:

    ["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",
            },
        },
    },

     法三:

    也可以利用lua的序列化将lua表转化为string,再将其给print出来;

    -- 序列化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 .. "{
    "
        for k, v in pairs(obj) do
            lua = lua .. "[" .. serialize(k) .. "]=" .. serialize(v) .. ",
    "
        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) .. ",
    "
            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
  • 相关阅读:
    Executors线程池
    解决HtmlAgilityPack无法获取form标签子节点的问题
    nohup不输出日志信息的方法,及linux重定向学习
    将博客从jekyll迁移到了hexo
    node-webkit中使用sqlite3(MAC平台)
    借助Nodejs在服务端使用jQuery采集17173游戏排行信息
    Shell脚本中的交互式命令处理
    通过桥接虚拟网卡使VMWare和宿主机实现双向通讯
    MySql使用show processlist查看正在执行的Sql语句
    Sql合并两个select查询
  • 原文地址:https://www.cnblogs.com/jadeboy/p/3972524.html
Copyright © 2020-2023  润新知