I wanted an iterator which returns all the values in a nested table.
An elegant method would be to use coroutines as at
http://www.lua.org/pil/9.3.html or http://snippets.luacode.org/?p=snippets/Iterating_over_a_tree_12
(Neither of these are functionally what I want - just use coroutines in an iterator)
but I don’t want the overhead of coroutines as I’ll be using the iterator quite a lot.
I have managed to work something out - see below.
It works fine but it seems rather brute force.
(Note that I’ve also returned the table, index and parent table for thoroughness)
I think the challenge is to work out how to have a recursive routine inside an iterator and my brain doesn’t quite stretch that far x:-|
Does anyone fancy a mid-week chalenge to come up with something more elegant?
Suhada
[lua]function nodes(t)
–Keep a stack of tables and indices into those
local tablestack = {t}
local indexstack = {0}
local function nodes_it(t)
local tabl
local index
while true do
tabl = tablestack[#tablestack]
index = indexstack[#indexstack]
index = index + 1 --Move to next value in current table
indexstack[#indexstack] = index
local value = tabl[index]
if (type(value)==“table”) then
–we need to look at the nested table so create another table and index on the stack
tablestack[#tablestack+1] = tabl[index]
indexstack[#indexstack+1] = 0
– And go round again with the child table
else
if (value == nil) then --We’ve come to the end of the table so:
–Remove last table reference
tablestack[#tablestack] = nil
indexstack[#indexstack] = nil
if (#tablestack == 0) then
–We’ve run out of tables so end
return nil,nil,nil,nil
end
–Otherwise go round again with the parent table
else
if (#tablestack == 1) then
–No parent
parent = nil
else
parent = tablestack[#tablestack-1]
end
return value,tabl,index,parent
end
end
end
end
return nodes_it, tabl
end
local t = {‘a’, ‘b’, {‘1’,‘2’}, ‘c’, {‘3’,‘4’},‘d’, ‘e’}
for value, tabl, index, parent in nodes(t) do
if (parent == nil) then parone=“none” else parone=parent[1] end
print(“value=”,value," table=",tabl," table[1]=",tabl[1]," index=",index," parent=",parent," parent[1]=",parone)
end[/lua]
Output:
value= a table= table: 03270428 table[1]= a index= 1 parent= nil parent[1]= none
value= b table= table: 03270428 table[1]= a index= 2 parent= nil parent[1]= none
value= 1 table= table: 032704C8 table[1]= 1 index= 1 parent= table: 03270428 parent[1]= a
value= 2 table= table: 032704C8 table[1]= 1 index= 2 parent= table: 03270428 parent[1]= a
value= c table= table: 03270428 table[1]= a index= 4 parent= nil parent[1]= none
value= 3 table= table: 03270518 table[1]= 3 index= 1 parent= table: 03270428 parent[1]= a
value= 4 table= table: 03270518 table[1]= 3 index= 2 parent= table: 03270428 parent[1]= a
value= d table= table: 03270428 table[1]= a index= 6 parent= nil parent[1]= none
value= e table= table: 03270428 table[1]= a index= 7 parent= nil parent[1]= none
[import]uid: 67842 topic_id: 26398 reply_id: 326398[/import]