Skip to content

Instantly share code, notes, and snippets.

@lorinc
Last active February 7, 2019 05:11
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 lorinc/2e8e5ab0ed0ef4728aabee53ea734ac8 to your computer and use it in GitHub Desktop.
Save lorinc/2e8e5ab0ed0ef4728aabee53ea734ac8 to your computer and use it in GitHub Desktop.
This is a function I wrote to support deeply nested data structures at Google in the Cloud Support BI pipeline.
-- iterator function to traverse nested tables
function iterate(tbl, parent)
parent = parent or {}
if (type(tbl)=="table") then
for key, value in pairs(tbl) do
iterate(value, table.extend(parent, key))
end
end
coroutine.yield(parent, tbl)
end
-- wraps the iterator, use this in for cycles
function traverse(root)
return coroutine.wrap(iterate), root
end
-- returns a copy of the table
function table.clone(tbl)
return {table.unpack(tbl)}
end
-- returns: table clone + added element
function table.extend(tbl, new_value)
local tbl = table.clone(tbl)
table.insert(tbl, new_value)
return tbl
end
--- example ---
tree = {
['a1'] = {
['b2'] = {'c3', nil},
['e2'] = {
['f3'] = {16, 'h4'},
[11] = {'y', 32},
[15] = 'foo'
},
['i2'] = {1, 2},
[56] = {'x', true}
},
['j1'] = 10,
['why not?'] = {},
[{'Is this', true}] = 10 -- iterator works fine with table indices
} -- but table.concat() does not
for parent, value in traverse(tree) do
print(table.concat(parent, '.'), value)
end
--[[
Prints:
a1.e2.15 foo
a1.e2.11.1 y
a1.e2.11.2 32
a1.e2.11 table: 0x12c9e40
a1.e2.f3.1 16
a1.e2.f3.2 h4
a1.e2.f3 table: 0x12c9df0
a1.e2 table: 0x12c7980
a1.56.1 x
a1.56.2 true
a1.56 table: 0x12c9f40
a1.i2.1 1
a1.i2.2 2
a1.i2 table: 0x12c9ec0
a1.b2.1 c3
a1.b2 table: 0x12c3e60
a1 table: 0x12c3e10
j1 10
why not? table: 0x12c9fc0
table: 0x12c9a80
------------------
(program exited with code: 0)
]]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment