# Posted By

kergoth on 12/18/06

# Statistics

Viewed 279 times
Favorited by 1 user(s)

# Lua: Descending Table Traversal Round 2: Iterator Object

/ Published in: Lua
`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 oendfunction 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,vendfunction traverse:iter(tname)	if tname then		self:enqueue(tname)	end	return function(...) return self:next(unpack(arg)) end, nil, nilendfunction traverse:enqueue(tname)	local v = _G[tname]	table.insert(self.queue, v)	self.names[v] = tnameendfunction traverse:reset()	self.names = {}	self.queue = {}endlocal 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)))endbar[1] = alphabar[2] = betabar[3] = thetabar[omega] = table: 0x510650foo[1] = 1foo[2] = 2foo[3] = 3foo[4] = 4foo[5] = 5foo[a] = table: 0x5102d0foo[c] = table: 0x510370foo[b] = table: 0x510320foo[d] = table: 0x5103c0foo.c[1] = barfoo.d[e] = table: 0x5104c0foo.d[f] = table: 0x510510foo.d.f[1] = moo`