lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]



On 29/01/15 06:27 PM, Sean Conner wrote:
It was thus said that the Great Tony Papadimitriou once stated:
Hi all,

I’m looking for the best (?) general way to implement *nested* iterators
in Lua (5.3, of course).

For example:  I have an iterator that returns single items when used in a
FOR .. IN loop.  Each item is treated somehow but that loop, and the
result I want it to become available in another iterator.

Easy, but I do NOT want to store all intermediate results in a table, and
then traverse the table again, as the size of the table could be too large
or even unknown while the iterator is running (until some condition
happens that terminates it).

In Python 3, for example, this would be very simple with each routine
using YIELD instead of RETURN, and iterators can be nested to an arbitrary
level.  But, in Lua, I can’t seem to find an obvious (memory efficient)
solution.  (I would love for Lua to have the same simplicity in this
regard.)

Perhaps explicit use of co-routines is one solution, but maybe there is a
more immediate way I missed.

Maybe someone can point me to some example.
   Here's an example that I think answers what you are asking:

	function iterator(a,b)
	  return coroutine.wrap(function()
	    for ai = 1 , #a do
	      for bi = 1 , #b do	
	        coroutine.yield(string.format("%s-%s",tostring(a[ai]),tostring(b[bi])))
               end
	    end
	  end)
	end

	A = { 1 , 2 , 3 , 4 , 5 }
	B = { "one" , "two" , "three" , "four" , "five" }
	
	for item in iterator(A,B) do
	  print(item)
	end

   -spc


function makeIterator()
  local tState = {}
  return stateHandler, tState, startValue
end

Use a tState instead of coroutines and/or closures. stateHandler is your iterator, it'll get tState as the first arg. startValue... you (should) know what that is.

--
Disclaimer: these emails are public and can be accessed from <TODO: get a non-DHCP IP and put it here>. If you do not agree with this, DO NOT REPLY.