Skip to content

Instantly share code, notes, and snippets.

@Akianonymus
Last active August 19, 2021 08:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Akianonymus/301483c34540fa80c8dd5728d4ef8194 to your computer and use it in GitHub Desktop.
Save Akianonymus/301483c34540fa80c8dd5728d4ef8194 to your computer and use it in GitHub Desktop.
Lua functions
-- https://www.codegrepper.com/code-examples/lua/lua+how+to+print+a+table
local function print_table(node, indent)
local cache, stack, output = {}, {}, {}
local depth = 1
local output_str = "{\n"
indent = indent or " "
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
key = tostring(k)
if type(v) == "number" or type(v) == "boolean" then
output_str = output_str .. string.rep(indent, depth) .. key .. " = " .. tostring(v)
elseif type(v) == "table" then
output_str = output_str .. string.rep(indent, depth) .. key .. " = {\n"
table.insert(stack, node)
table.insert(stack, v)
cache[node] = cur_index + 1
break
else
if type(tonumber(key)) == "number" then
output_str = output_str .. string.rep(indent, depth) .. "'" .. tostring(v) .. "'"
else
output_str = output_str .. string.rep(indent, depth) .. key .. " = '" .. tostring(v) .. "'"
end
end
if cur_index == size then
output_str = output_str .. "\n" .. string.rep(indent, depth - 1) .. "}"
else
output_str = output_str .. ","
end
else
-- close the table
if cur_index == size then
output_str = output_str .. "\n" .. string.rep(indent, depth - 1) .. "}"
end
end
cur_index = cur_index + 1
end
if size == 0 then
output_str = output_str .. "\n" .. string.rep(indent, 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
-- https://gist.github.com/revolucas/184aec7998a6be5d2f61b984fac1d7f7
local function table_merge(into, from)
local stack = {}
local node1 = into
local node2 = from
while true do
for k, v in pairs(node2) do
if type(v) == "table" and type(node1[k]) == "table" then
table.insert(stack, { node1[k], node2[k] })
else
node1[k] = v
end
end
if #stack > 0 then
local t = stack[#stack]
node1, node2 = t[1], t[2]
stack[#stack] = nil
else
break
end
end
return into
end
-- Base code: https://gist.github.com/revolucas/184aec7998a6be5d2f61b984fac1d7f7
-- Changes over it: preserving table 1 contents and also update with table b, without duplicating
-- 1st arg - base table, 2nd arg - table to merge
local function merge_table_preserve(into, from)
-- make sure both are table
if type(into) ~= "table" or type(from) ~= "table" then
return 1
end
local stack, seen = {}, {}
local table1, table2 = into, from
while true do
for k, v in pairs(table2) do
if type(v) == "table" and type(table1[k]) == "table" then
table.insert(stack, { table1[k], table2[k] })
else
local present = seen[v] or false
if not present then
-- add the value to seen table until value is found
-- todo: maybe improve this
for _, value in pairs(table1) do
if value == v then
present = true
break
end
end
end
seen[v] = true
if not present then
-- if type is number, then it is a sub table value, so append
if type(k) == "number" then
table1[#table1 + 1] = v
else
table1[k] = v
end
end
end
end
if #stack > 0 then
local t = stack[#stack]
table1, table2 = t[1], t[2]
stack[#stack] = nil
else
break
end
end
return into
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment