Skip to content

Instantly share code, notes, and snippets.

@revolucas
Last active April 16, 2024 15:13
Show Gist options
  • Save revolucas/dd1ecccfca32d558fddf70ddb39eb8a6 to your computer and use it in GitHub Desktop.
Save revolucas/dd1ecccfca32d558fddf70ddb39eb8a6 to your computer and use it in GitHub Desktop.
[Lua] Print table function for deeply nested tables
--[[
Most pure lua print table functions I've seen have a problem with deep recursion and tend to cause a stack overflow when
going too deep. This print table function that I've written does not have this problem. It should also be capable of handling
really large tables due to the way it handles concatenation. In my personal usage of this function, it outputted 63k lines to
file in about a second.
The output also keeps lua syntax and the script can easily be modified for simple persistent storage by writing the output to
file if modified to allow only number, boolean, string and table data types to be formatted.
author: Alundaio (aka Revolucas)
--]]
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 (#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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment