Revision: 2024
Updated Code
at December 18, 2006 08:09 by kergoth
Updated Code
traverse = {} function traverse:new(tname) local o = {} o.names = {} o.queue = {} o.cur = { tbl = nil, path = nil, state = nil, } local mt = {} function mt:__call(tn) return o:iter(tn) end mt.__index = self setmetatable(o, mt) if tname then o:enqueue(tname) end return o end function traverse:next() local v local names, queue, cur = self.names, self.queue, self.cur local function _poptbl() if cur.tbl then names[cur.tbl] = nil end cur.tbl = table.remove(queue, 1) cur.path = names[cur.tbl] cur.state = nil end repeat -- Find something to return to the user... if not cur.state then -- Pop a new table off the stack _poptbl() if not cur.tbl then -- No more tables to process return nil end end cur.state,v = next(cur.tbl, cur.state) until cur.state if type(v) == "table" then local path = cur.path.."."..cur.state names[v] = path table.insert(queue, v) end return cur.path,cur.tbl,cur.state,v end function traverse:iter(tname) if tname then self:enqueue(tname) end return function(...) return self:next(unpack(arg)) end, nil, nil end function traverse:enqueue(tname) local v = _G[tname] table.insert(self.queue, v) self.names[v] = tname end function traverse:reset() self.names = {} self.queue = {} end local traverse_mt = { __call = function(self, tname) if tname then return self:new(tname):iter() else return self:new() end end } setmetatable(traverse, traverse_mt) foo = {a={},b={},c={"bar"},d={e={},f={"moo"}},1,2,3,4,5} bar = {"alpha", "beta", "theta", omega = {}} local mytraverser = traverse() mytraverser:enqueue("bar") mytraverser:enqueue("foo") for p,t,k,v in mytraverser() do --for p,t,k,v in traverse('foo') do print(string.format("%s[%s] = %s",tostring(p),tostring(k),tostring(v))) end bar[1] = alpha bar[2] = beta bar[3] = theta bar[omega] = table: 0x510650 foo[1] = 1 foo[2] = 2 foo[3] = 3 foo[4] = 4 foo[5] = 5 foo[a] = table: 0x5102d0 foo[c] = table: 0x510370 foo[b] = table: 0x510320 foo[d] = table: 0x5103c0 foo.c[1] = bar foo.d[e] = table: 0x5104c0 foo.d[f] = table: 0x510510 foo.d.f[1] = moo
Revision: 2023
Initial Code
Initial URL
Initial Description
Initial Title
Initial Tags
Initial Language
at December 18, 2006 08:06 by kergoth
Initial Code
traverse = {} function traverse:new(tname) local o = {} o.names = {} o.queue = {} o.cur = { tbl = nil, path = nil, state = nil, } local mt = {} function mt:__call(tn) return o:iter(tn) end mt.__index = self setmetatable(o, mt) if tname then o:enqueue(tname) end return o end function traverse:next() local v local names, queue, cur = self.names, self.queue, self.cur local function _poptbl() if cur.tbl then names[cur.tbl] = nil end cur.tbl = table.remove(queue, 1) cur.path = names[cur.tbl] cur.state = nil end repeat -- Find something to return to the user... if not cur.state then -- Pop a new table off the stack _poptbl() if not cur.tbl then -- No more tables to process return nil end end cur.state,v = next(cur.tbl, cur.state) until cur.state if type(v) == "table" then local path = cur.path.."."..cur.state names[v] = path table.insert(queue, v) end return cur.path,cur.tbl,cur.state,v end function traverse:iter(tname) if tname then self:enqueue(tname) end return function(...) return self:next(unpack(arg)) end, nil, nil end function traverse:enqueue(tname) local v = _G[tname] table.insert(self.queue, v) self.names[v] = tname end function traverse:reset() self.names = {} self.queue = {} end local traverse_mt = { __call = function(self, tname) if tname then return self:new(tname):iter() else return self:new() end end } setmetatable(traverse, traverse_mt) foo = {a={},b={},c={"bar"},d={e={},f={"moo"}},1,2,3,4,5} bar = {"alpha", "beta", "theta", omega = {}} local mytraverser = traverse() mytraverser:enqueue("bar") mytraverser:enqueue("foo") for p,t,k,v in mytraverser() do --for p,t,k,v in traverse('foo') do print(string.format("%s[%s] = %s",tostring(p),tostring(k),tostring(v))) end bar[1] = alpha bar[2] = beta bar[3] = theta bar[omega] = table: 0x510650 foo[1] = 1 foo[2] = 2 foo[3] = 3 foo[4] = 4 foo[5] = 5 foo[a] = table: 0x5102d0 foo[c] = table: 0x510370 foo[b] = table: 0x510320 foo[d] = table: 0x5103c0 foo.c[1] = bar foo.d[e] = table: 0x5104c0 foo.d[f] = table: 0x510510 foo.d.f[1] = moo
Initial URL
Initial Description
Initial Title
Lua: Descending Table Traversal Round 2: Iterator Object
Initial Tags
object
Initial Language
Lua