We Recommend

Smarty PHP Template Programming And Applications Smarty PHP Template Programming And Applications
Smarty is a templating engine for PHP. Designers who are used to working with HTML files can work with Smarty templates, which are HTML files with simple tags while programmers work with the underlying PHP code. The Smarty engine brings the code and templates together. The result of all this is that designers can concentrate on designing, programmers can concentrate on programming, and they don't need to get in each others way so much.


Posted By

kergoth on 12/18/06


Tagged

object oop tables iteration lua classes traversal functables metatables


Versions (?)


Who likes this?

1 person has marked this snippet as a favorite

lenn0x


Lua: Descending Table Traversal Round 2: Iterator Object


Published in: Lua 


  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
  38. -- Find something to return to the user...
  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

Report this snippet 

You need to login to post a comment.