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