Lua 自定义打印table函数

前言

一直用lua 作为游戏脚本语言来编程,而table在lua的数据结构中占据了大半壁江山,所以几乎每天的编程都离不开对table的使用,lua的table确实好用,插入、删除、查询都非常的方便,但是用多了也就渐渐的发现了一些问题,比如不知道table中都有哪些值,调试的时候面对巨大的table不知从何下手等等,所以我就有了一个想法,想看看lua中能不能直接打印table的值,网上看了一些文章发现都不太适合,决定自己动手写一个,要打印table这样的结构当然得用递归思想了,话不多说,直接上代码和大家分享一下。

代码示例

function dumptree(obj, width)

    -- 递归打印函数
    local dump_obj;
    local end_flag = {};

    local function make_indent(layer, is_end)
        local subIndent = string.rep("  ", width)
        local indent = "";
        end_flag[layer] = is_end;
        local subIndent = string.rep("  ", width)
        for index = 1, layer - 1 do
            if end_flag[index] then
                indent = indent.." "..subIndent
            else
                indent = indent.."|"..subIndent
            end
        end

        if is_end then
            return indent.."└"..string.rep("─", width).." "
        else
            return indent.."├"..string.rep("─", width).." "
        end
    end

    local function make_quote(str)
        str = string.gsub(str, "[%c\\\"]", {
            ["\t"] = "\\t",
            ["\r"] = "\\r",
            ["\n"] = "\\n",
            ["\""] = "\\\"",
            ["\\"] = "\\\\",
        })
        return "\""..str.."\""
    end

    local function dump_key(key)
        if type(key) == "number" then
            return key .. "] "
        elseif type(key) == "string" then
            return tostring(key).. ": "
        end
    end

    local function dump_val(val, layer)
        if type(val) == "table" then
            return dump_obj(val, layer)
        elseif type(val) == "string" then
            return make_quote(val)
        else
            return tostring(val)
        end
    end

    local function count_elements(obj)
        local count = 0
        for k, v in pairs(obj) do
            count = count + 1
        end
        return count
    end

    dump_obj = function(obj, layer)
        if type(obj) ~= "table" then
            return count_elements(obj)
        end

        layer = layer + 1
        local tokens = {}
        local max_count = count_elements(obj)
        local cur_count = 1
        for k, v in pairs(obj) do
            local key_name = dump_key(k)
            if type(v) == "table" then
                key_name = key_name.."\n"
            end
            table.insert(tokens, make_indent(layer, cur_count == max_count) 
                .. key_name .. dump_val(v, layer))
            cur_count = cur_count + 1
        end

        -- 处理空table
        if max_count == 0 then
            table.insert(tokens, make_indent(layer, true) .. "{ }")
        end

        return table.concat(tokens, "\n")
    end

    if type(obj) ~= "table" then
        return "the params you input is "..type(obj)..
        ", not a table, the value is --> "..tostring(obj)
    end

    width = width or 2
    return "root-->"..tostring(obj).."\n"..dump_obj(obj, 0)
end

运行示例

local t = {
    a = 1,
    b = 2,
    [1] = 34,
    ["1"] =56,
    pos = {
        x = 100,
        y = 200,
        z = 400,
        target = {
            pos = {
                x = 666,
                y = 456,
            },
            src = "name",
            dest = nil,
            from = "china \n beijing"
        }
    },  
    [88] = 88888,
    [9.7] = 22222,
    func = function()
        print("this is a function")
    end,
    ["key"] = "value",
    [98] = {
        name = "albert",
        age = "18",
    },
    ["98"] = {},
}

-- 调用函数运行
print(dumptree(t))

运行结果

root-->table: 0031D748
├── a: 1
├── b: 2
├── 9.7] 22222
├── 1] 34
├── 98] 
|    ├── name: "albert"
|    └── age: "18"
├── key: "value"
├── func: function: 00318140
├── 88] 88888
├── 98: 
|    └── { }
├── 1: 56
└── pos: 
     ├── y: 200
     ├── x: 100
     ├── target: 
     |    ├── src: "name"
     |    ├── from: "china \n beijing"
     |    └── pos: 
     |         ├── y: 456
     |         └── x: 666
     └── z: 400

总结

  • 这个函数是以树形的结构打印table,看起来比原型打印更加清晰。
  • 结果中将一个空的table表示为{}的形式。
  • 参数width主要是控制树杈的宽度,默认为2,会出现图中所表现的结果。
  • 如果在使用过程中有什么问题,欢迎大家及时指出来,我会及时改正。
  • 17
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 33
    评论
评论 33
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

AlbertS

常来“玩”啊~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值