Как сбросить таблицу на консоль?
у меня возникли проблемы с отображением содержимого таблицы, которая содержит вложенные таблицы (N-deep). Я хотел бы просто сбросить его на std out или консоль через print
заявление или что-то быстрое и грязное, но я не могу выяснить, как. Я ищу грубый эквивалент, который я получу при печати NSDictionary
использование gdb.
11 ответов:
Не стесняйтесь просматривать Lua Wiki на сериализации таблицы. В нем перечислены несколько способов сброса таблицы на консоль.
вы просто должны выбрать, какой из них подходит вам лучше всего. Есть много способов сделать это, но я обычно использую один из пальчиковые:
> t = { a = { b = { c = "Hello world!", 1 }, 2, d = { 3 } } } > require 'pl.pretty'.dump(t) { a = { d = { 3 }, b = { c = "Hello world!", 1 }, 2 } }
Я знаю, что этот вопрос уже отмечен как ответ, но позвольте мне подключить свою собственную библиотеку здесь. Это называется инспекция.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 -- }
он правильно отступает от подтаблиц и обрабатывает "рекурсивные таблицы" (таблицы, которые содержат ссылки на себя) правильно, поэтому он не попадает в бесконечные циклы. Он сортирует значения разумным способом. Он также выводит метатаблиц информации.
С уважением!
Я нашел это полезным. Потому что если рекурсия он может печатать вложенные таблицы тоже.
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
например
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))
выдает следующий результат:
люди: { [1] = { ["адрес"] = 16 Long Street, ["телефон"] = 123456, ["имя"] = Фред,} ,[2] = { ["Адрес"] = 16 Лонг Street, ["phone"] = 123456, ["name"] = Вильма,} ,[3] = { ["Адрес"] = 17 Лонг-стрит, ["телефон"] = 123457, ["имя"] = Барни,},}
нашел это:
-- 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
отсюда https://gist.github.com/ripter/4270799
работает очень хорошо для меня...
большинство чистых функций таблицы печати lua, которые я видел, имеют проблему с глубокой рекурсией и, как правило, вызывают переполнение стека, когда идут слишком глубоко. Этот отпечаток табличная функция, которую я написал, не имеет этой проблемы. Он также должен быть способен обрабатывать действительно большие таблицы из-за того, как он обрабатывает конкатенацию. В моем личном использовании этой функции он выводил 63k строк в файл примерно за секунду.
вывод также сохраняет синтаксис lua, и скрипт можно легко изменить для простое постоянное хранилище путем записи выходных данных в файл, если они изменены, чтобы разрешить форматируются только числовые, логические, строковые и табличные типы данных.
function print_table(node) -- to make output beautiful local function tab(amt) local str = "" for i=1,amt do str = str .. "\t" end return str end 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 .. tab(depth) .. key .. " = "..tostring(v) elseif (type(v) == "table") then output_str = output_str .. tab(depth) .. key .. " = {\n" table.insert(stack,node) table.insert(stack,v) cache[node] = cur_index+1 break else output_str = output_str .. tab(depth) .. key .. " = '"..tostring(v).."'" end if (cur_index == size) then output_str = output_str .. "\n" .. tab(depth-1) .. "}" else output_str = output_str .. "," end else -- close the table if (cur_index == size) then output_str = output_str .. "\n" .. tab(depth-1) .. "}" end end cur_index = cur_index + 1 end if (size == 0) then output_str = output_str .. "\n" .. tab(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
вот пример:
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)
выход:
{ [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' } }
Как упоминалось ранее, вы должны написать его. Вот моя скромная версия: (super basic one)
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
пример:
local mytbl = { ['1']="a", 2, 3, b="c", t={d=1} } tprint(mytbl)
выход (Lua 5.0):
table[1] = 2 table[2] = 3 table["1"] = "a" table["t"]["d"] = 1 table["b"] = "c"
на
table.tostring
metehod of metalua - это на самом деле очень полная. Он имеет дело с вложенными таблицами, уровень отступа является изменчивым, ... См.https://github.com/fab13n/metalua/blob/master/src/lib/metalua/table2.lua
Это моя версия, которая поддерживает исключение таблиц и userdata
-- Lua Table View by Elertan table.print = function(t, exclusions) local nests = 0 if not exclusions then exclusions = {} end local recurse = function(t, recurse, exclusions) indent = function() for i = 1, nests do io.write(" ") end end local excluded = function(key) for k,v in pairs(exclusions) do if v == key then return true end end return false end local isFirst = true for k,v in pairs(t) do if isFirst then indent() print("|") isFirst = false end if type(v) == "table" and not excluded(k) then indent() print("|-> "..k..": "..type(v)) nests = nests + 1 recurse(v, recurse, exclusions) elseif excluded(k) then indent() print("|-> "..k..": "..type(v)) elseif type(v) == "userdata" or type(v) == "function" then indent() print("|-> "..k..": "..type(v)) elseif type(v) == "string" then indent() print("|-> "..k..": ".."\""..v.."\"") else indent() print("|-> "..k..": "..v) end end nests = nests - 1 end nests = 0 print("### START TABLE ###") for k,v in pairs(t) do print("root") if type(v) == "table" then print("|-> "..k..": "..type(v)) nests = nests + 1 recurse(v, recurse, exclusions) elseif type(v) == "userdata" or type(v) == "function" then print("|-> "..k..": "..type(v)) elseif type(v) == "string" then print("|-> "..k..": ".."\""..v.."\"") else print("|-> "..k..": "..v) end end print("### END TABLE ###") end
Это пример
t = { location = { x = 10, y = 20 }, size = { width = 100000000, height = 1000, }, name = "Sidney", test = { hi = "lol", }, anotherone = { 1, 2, 3 } } table.print(t, { "test" })
принты:
### START TABLE ### root |-> size: table | |-> height: 1000 |-> width: 100000000 root |-> location: table | |-> y: 20 |-> x: 10 root |-> anotherone: table | |-> 1: 1 |-> 2: 2 |-> 3: 3 root |-> test: table | |-> hi: "lol" root |-> name: "Sidney" ### END TABLE ###
обратите внимание, что корень не удалить исключения
боюсь, вам придется закодировать его самостоятельно. Я написал это, и это может быть вам полезно
function printtable(table, indent) indent = indent or 0; local keys = {}; for k in pairs(table) do keys[#keys+1] = k; table.sort(keys, function(a, b) local ta, tb = type(a), type(b); if (ta ~= tb) then return ta < tb; else return a < b; end end); end print(string.rep(' ', indent)..'{'); indent = indent + 1; for k, v in pairs(table) do local key = k; if (type(key) == 'string') then if not (string.match(key, '^[A-Za-z_][0-9A-Za-z_]*$')) then key = "['"..key.."']"; end elseif (type(key) == 'number') then key = "["..key.."]"; end if (type(v) == 'table') then if (next(v)) then printf("%s%s =", string.rep(' ', indent), tostring(key)); printtable(v, indent); else printf("%s%s = {},", string.rep(' ', indent), tostring(key)); end elseif (type(v) == 'string') then printf("%s%s = %s,", string.rep(' ', indent), tostring(key), "'"..v.."'"); else printf("%s%s = %s,", string.rep(' ', indent), tostring(key), tostring(v)); end end indent = indent - 1; print(string.rep(' ', indent)..'}'); end
--~ print a table function printTable(list, i) local listString = '' --~ begin of the list so write the { if not i then listString = listString .. '{' end i = i or 1 local element = list[i] --~ it may be the end of the list if not element then return listString .. '}' end --~ if the element is a list too call it recursively if(type(element) == 'table') then listString = listString .. printTable(element) else listString = listString .. element end return listString .. ', ' .. printTable(list, i + 1) end local table = {1, 2, 3, 4, 5, {'a', 'b'}, {'G', 'F'}} print(printTable(table))
Привет человек, я написал siple код, который делает это в чистом Lua, он имеет ошибку (написать кома после последнего элемента списка), но как я написал его быстро, как прототип я позволю ему адаптировать его к вашим потребностям.
как JSON (вы можете "украсить" в IDE позже):
local function format_any_value(obj, buffer) local _type = type(obj) if _type == "table" then buffer[#buffer + 1] = '{"' for key, value in next, obj, nil do buffer[#buffer + 1] = tostring(key) .. '":' format_any_value(value, buffer) buffer[#buffer + 1] = ',"' end buffer[#buffer] = '}' -- note the overwrite elseif _type == "string" then buffer[#buffer + 1] = '"' .. obj .. '"' elseif _type == "boolean" or _type == "number" then buffer[#buffer + 1] = tostring(obj) else buffer[#buffer + 1] = '"???' .. _type .. '???"' end end
использование:
local function format_as_json(obj) if obj == nil then return "null" else local buffer = {} format_any_value(obj, buffer) return table.concat(buffer) end end local function print_as_json(obj) print(_format_as_json(obj)) end print_as_json {1, 2, 3} print_as_json(nil) print_as_json("string") print_as_json {[1] = 1, [2] = 2, three = { { true } }, four = "four"}
кстати, я также написал несколько других решений: a очень быстро один, и один со специальными символами экранирования:https://github.com/vn971/fast_json_encode