# Posted By

kergoth on 12/18/06

# Statistics

Viewed 596 times
Favorited by 1 user(s)

# Lua: Descending Table Traversal Round 2: Iterator Object

/ Published in: Lua

Copy this code and paste it in your HTML
1. traverse = {}
2. function traverse:new(tname)
3. local o = {}
4. o.names = {}
5. o.queue = {}
6. o.cur = {
7. tbl = nil,
8. path = nil,
9. state = nil,
10. }
11.
12. local mt = {}
13. function mt:__call(tn)
14. return o:iter(tn)
15. end
16. mt.__index = self
17. setmetatable(o, mt)
18.
19. if tname then
20. o:enqueue(tname)
21. end
22. return o
23. end
24. function traverse:next()
25. local v
26. local names, queue, cur = self.names, self.queue, self.cur
27.
28. local function _poptbl()
29. if cur.tbl then
30. names[cur.tbl] = nil
31. end
32. cur.tbl = table.remove(queue, 1)
33. cur.path = names[cur.tbl]
34. cur.state = nil
35. end
36.
37. repeat
39. if not cur.state then
40. -- Pop a new table off the stack
41. _poptbl()
42. if not cur.tbl then
43. -- No more tables to process
44. return nil
45. end
46. end
47. cur.state,v = next(cur.tbl, cur.state)
48. until cur.state
49.
50. if type(v) == "table" then
51. local path = cur.path.."."..cur.state
52. names[v] = path
53. table.insert(queue, v)
54. end
55. return cur.path,cur.tbl,cur.state,v
56. end
57. function traverse:iter(tname)
58. if tname then
59. self:enqueue(tname)
60. end
61. return function(...) return self:next(unpack(arg)) end, nil, nil
62. end
63. function traverse:enqueue(tname)
64. local v = _G[tname]
65. table.insert(self.queue, v)
66. self.names[v] = tname
67. end
68. function traverse:reset()
69. self.names = {}
70. self.queue = {}
71. end
72. local traverse_mt = {
73. __call = function(self, tname)
74. if tname then
75. return self:new(tname):iter()
76. else
77. return self:new()
78. end
79. end
80. }
81. setmetatable(traverse, traverse_mt)
82. foo = {a={},b={},c={"bar"},d={e={},f={"moo"}},1,2,3,4,5}
83. bar = {"alpha", "beta", "theta", omega = {}}
84.
85. local mytraverser = traverse()
86. mytraverser:enqueue("bar")
87. mytraverser:enqueue("foo")
88. for p,t,k,v in mytraverser() do
89. --for p,t,k,v in traverse('foo') do
90. print(string.format("%s[%s] = %s",tostring(p),tostring(k),tostring(v)))
91. end
92. bar[1] = alpha
93. bar[2] = beta
94. bar[3] = theta
95. bar[omega] = table: 0x510650
96. foo[1] = 1
97. foo[2] = 2
98. foo[3] = 3
99. foo[4] = 4
100. foo[5] = 5
101. foo[a] = table: 0x5102d0
102. foo[c] = table: 0x510370
103. foo[b] = table: 0x510320
104. foo[d] = table: 0x5103c0
105. foo.c[1] = bar
106. foo.d[e] = table: 0x5104c0
107. foo.d[f] = table: 0x510510
108. foo.d.f[1] = moo