如何将表转储到控制台?

Cli*_*iff 92 lua

我在显示包含嵌套表(n-deep)的表的内容时遇到问题.我想通过print声明或快速而肮脏的东西将它转储到std out或控制台,但我无法弄清楚如何.我正在寻找打印NSDictionary使用gdb 时得到的粗略等效物.

kik*_*ito 86

我知道这个问题已被标记为已回答,但让我在这里插入我自己的库.它叫做inspect.lua,你可以在这里找到它:

https://github.com/kikito/inspect.lua

它只是一个文件,您可以从任何其他文件中获取.它返回一个函数,将任何Lua值转换为人类可读的字符串:

local inspect = require('inspect')

print(inspect({1,2,3})) -- {1, 2, 3}
print(inspect({a=1,b=2})
-- {
--   a = 1
--   b = 2
-- }
Run Code Online (Sandbox Code Playgroud)

它正确缩进子表,并正确处理"递归表"(包含对自身的引用的表),因此它不会进入无限循环.它以合理的方式对价值进行排序.它还可以打印metatable信息.

问候!

  • 将inspect.lua 添加到wiki。 (2认同)
  • @Hack-R它是关于luarocks:`luarocks install inspect` (2认同)
  • @JohnLee 但是请注意,在该库的最新版本中,它将非常努力地不重复同一个表多次。相反,如果它们出现多次,它会将它们压缩到“<table n>”https://github.com/kikito/inspect.lua/blob/master/spec/inspect_spec.lua#L171 (2认同)

Mat*_*att 57

我发现这个有用了.因为如果递归它也可以打印嵌套表.

function dump(o)
   if type(o) == 'table' then
      local s = '{ '
      for k,v in pairs(o) do
         if type(k) ~= 'number' then k = '"'..k..'"' end
         s = s .. '['..k..'] = ' .. dump(v) .. ','
      end
      return s .. '} '
   else
      return tostring(o)
   end
end
Run Code Online (Sandbox Code Playgroud)

例如

local people = {
   {
      name = "Fred",
      address = "16 Long Street",
      phone = "123456"
   },

   {
      name = "Wilma",
      address = "16 Long Street",
      phone = "123456"
   },

   {
      name = "Barney",
      address = "17 Long Street",
      phone = "123457"
   }

}

print("People:", dump(people))
Run Code Online (Sandbox Code Playgroud)

产生以下输出:

人物:{[1] = {["地址"] = 16长街,["电话"] = 123456,["名称"] =弗雷德,},[2] = {["地址"] = 16长街,["phone"] = 123456,["name"] = Wilma,},[3] = {["address"] = 17 Long Street,["phone"] = 123457,["name"] = Barney, },}

  • 分享一些不需要外部库的东西做得很好。 (8认同)
  • 这不是我写的。我在某处找到了它并对其进行了修改以生成可以打印的字符串。很乐意感谢原作者。 (2认同)
  • 为了方便在主代码之外进行调试,我添加了 `elseif type(o) == "string" then return tostring("\"" .. o .. "\"")`。现在我可以使用输出来测试硬编码表。 (2认同)

Mic*_*man 48

随意浏览表序列化上Lua Wiki.它列出了有关如何将表转储到控制台的几种方法.

您只需选择最适合您的选择.有很多方法可以做到,但我通常最终使用Penlight中的那个:

> t = { a = { b = { c = "Hello world!", 1 }, 2, d = { 3 } } }
> require 'pl.pretty'.dump(t)
{
  a = {
    d = {
      3
    },
    b = {
      c = "Hello world!",
      1
    },
    2
  }
}
Run Code Online (Sandbox Code Playgroud)

  • @Cliff luarocks安装penlight (6认同)
  • 愚蠢甚至更多新手问题:我如何安装像pl.pretty这样的扩展程序?如果我可以做一些像宝石安装这样的东西,而不是展开焦油球并在我的高清上找到理想的位置来定位东西,那就太好了.有快速/无痛的"按照这种方式"吗? (4认同)

JCH*_*H2k 17

发现了这个:

-- Print contents of `tbl`, with indentation.
-- `indent` sets the initial level of indentation.
function tprint (tbl, indent)
  if not indent then indent = 0 end
  for k, v in pairs(tbl) do
    formatting = string.rep("  ", indent) .. k .. ": "
    if type(v) == "table" then
      print(formatting)
      tprint(v, indent+1)
    elseif type(v) == 'boolean' then
      print(formatting .. tostring(v))      
    else
      print(formatting .. v)
    end
  end
end
Run Code Online (Sandbox Code Playgroud)

从这里 https://gist.github.com/ripter/4270799

对我来说效果很好......


Alu*_*aio 13

我见过的大多数纯lua打印表函数都有深度递归的问题,并且当进行得太深时往往会导致堆栈溢出.我写的这个打印表功能没有这个问题.由于它处理串联的方式,它还应该能够处理非常大的表.在我个人使用这个功能的过程中,它在大约一秒钟内输出63k行文件.

输出还保留了lua语法,并且通过将输出写入文件(如果已修改为仅允许格式化数字,布尔,字符串和表格数据类型),可以轻松地修改脚本以实现简单的持久存储.

function print_table(node)
    local cache, stack, output = {},{},{}
    local depth = 1
    local output_str = "{\n"

    while true do
        local size = 0
        for k,v in pairs(node) do
            size = size + 1
        end

        local cur_index = 1
        for k,v in pairs(node) do
            if (cache[node] == nil) or (cur_index >= cache[node]) then

                if (string.find(output_str,"}",output_str:len())) then
                    output_str = output_str .. ",\n"
                elseif not (string.find(output_str,"\n",output_str:len())) then
                    output_str = output_str .. "\n"
                end

                -- This is necessary for working with HUGE tables otherwise we run out of memory using concat on huge strings
                table.insert(output,output_str)
                output_str = ""

                local key
                if (type(k) == "number" or type(k) == "boolean") then
                    key = "["..tostring(k).."]"
                else
                    key = "['"..tostring(k).."']"
                end

                if (type(v) == "number" or type(v) == "boolean") then
                    output_str = output_str .. string.rep('\t',depth) .. key .. " = "..tostring(v)
                elseif (type(v) == "table") then
                    output_str = output_str .. string.rep('\t',depth) .. key .. " = {\n"
                    table.insert(stack,node)
                    table.insert(stack,v)
                    cache[node] = cur_index+1
                    break
                else
                    output_str = output_str .. string.rep('\t',depth) .. key .. " = '"..tostring(v).."'"
                end

                if (cur_index == size) then
                    output_str = output_str .. "\n" .. string.rep('\t',depth-1) .. "}"
                else
                    output_str = output_str .. ","
                end
            else
                -- close the table
                if (cur_index == size) then
                    output_str = output_str .. "\n" .. string.rep('\t',depth-1) .. "}"
                end
            end

            cur_index = cur_index + 1
        end

        if (size == 0) then
            output_str = output_str .. "\n" .. string.rep('\t',depth-1) .. "}"
        end

        if (#stack > 0) then
            node = stack[#stack]
            stack[#stack] = nil
            depth = cache[node] == nil and depth + 1 or depth - 1
        else
            break
        end
    end

    -- This is necessary for working with HUGE tables otherwise we run out of memory using concat on huge strings
    table.insert(output,output_str)
    output_str = table.concat(output)

    print(output_str)
end
Run Code Online (Sandbox Code Playgroud)

这是一个例子:

local t = {
    ["abe"] = {1,2,3,4,5},
    "string1",
    50,
    ["depth1"] = { ["depth2"] = { ["depth3"] = { ["depth4"] = { ["depth5"] = { ["depth6"] = { ["depth7"]= { ["depth8"] = { ["depth9"] = { ["depth10"] = {1000}, 900}, 800},700},600},500}, 400 }, 300}, 200}, 100},
    ["ted"] = {true,false,"some text"},
    "string2",
    [function() return end] = function() return end,
    75
}

print_table(t)
Run Code Online (Sandbox Code Playgroud)

输出:

{
    [1] = 'string1',
    [2] = 50,
    [3] = 'string2',
    [4] = 75,
    ['abe'] = {
        [1] = 1,
        [2] = 2,
        [3] = 3,
        [4] = 4,
        [5] = 5
    },
    ['function: 06472B70'] = 'function: 06472A98',
    ['depth1'] = {
        [1] = 100,
        ['depth2'] = {
            [1] = 200,
            ['depth3'] = {
                [1] = 300,
                ['depth4'] = {
                    [1] = 400,
                    ['depth5'] = {
                        [1] = 500,
                        ['depth6'] = {
                            [1] = 600,
                            ['depth7'] = {
                                [1] = 700,
                                ['depth8'] = {
                                    [1] = 800,
                                    ['depth9'] = {
                                        [1] = 900,
                                        ['depth10'] = {
                                            [1] = 1000
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    },
    ['ted'] = {
        [1] = true,
        [2] = false,
        [3] = 'some text'
    }
}
Run Code Online (Sandbox Code Playgroud)


小智 5

如前所述,您必须编写它。这是我的谦虚版本:(超级基本版本)

function tprint (t, s)
    for k, v in pairs(t) do
        local kfmt = '["' .. tostring(k) ..'"]'
        if type(k) ~= 'string' then
            kfmt = '[' .. k .. ']'
        end
        local vfmt = '"'.. tostring(v) ..'"'
        if type(v) == 'table' then
            tprint(v, (s or '')..kfmt)
        else
            if type(v) ~= 'string' then
                vfmt = tostring(v)
            end
            print(type(t)..(s or '')..kfmt..' = '..vfmt)
        end
    end
end
Run Code Online (Sandbox Code Playgroud)

例:

local mytbl = { ['1']="a", 2, 3, b="c", t={d=1} }
tprint(mytbl)
Run Code Online (Sandbox Code Playgroud)

输出(Lua 5.0):

table[1] = 2
table[2] = 3
table["1"] = "a"
table["t"]["d"] = 1
table["b"] = "c"
Run Code Online (Sandbox Code Playgroud)