如何在Lua中的二维表上创建迭代器?

kik*_*ito 4 lua iterator loops multidimensional-array

我有一个由表格组成的lua表,所以它是二维的:root - > child - > grandchild.

此层次结构的所有级别都不保证是"类似阵列".第一级具有"零间隙"的整数,第二级甚至不用整数(而是按表)索引.

有问题的表是l​​ib中的私有结构.我想为库用户提供解析其孙子的方法.我不太关心它们被解析的顺序,只要它们都是.

我想到的第一件事就是使用一个接受回调的函数:

-- this scope has access to root 
function eachGrandChild(callback)
  for _,child in pairs(root) do
    for index,grandChild in pairs(child)
      callback(index, grandChild)
    end
  end
end
Run Code Online (Sandbox Code Playgroud)

用法:

-- no access to root, only to eachGrandChild
eachGrandChild(function(index, grandChild) print(index, grandChild) end)
Run Code Online (Sandbox Code Playgroud)

这很了解.

我的问题是:我可以使用迭代器提供类似的功能吗?

我正在谈论允许我这样做的事情:

for index,grandChild in iterator() do
  print(index, grandChild)
end
Run Code Online (Sandbox Code Playgroud)

我已经考虑了一段时间,但我无法破解它.我见过的所有例子都使用数字来轻松地"管理每次迭代的迭代器状态".由于我没有数字,我有点卡住了.

Mud*_*Mud 7

协同程序使编写这种迭代器变得容易.协程是一个函数,其执行可以暂停和恢复,在概念上就像一个线程.一个协程可以包含深度嵌套的循环,从最内层的循环中产生一个值,然后在恢复时从它停止的地方继续.当它产生时,恢复它的调用者可以接收产生的值.

在你的情况,转换eachGrandChild成一个发生器功能产生孙子.

function eachGrandChild(root)
  for _,child in pairs(root) do
    for index,grandChild in pairs(child) do
      coroutine.yield(index, grandChild)
    end
  end
end
Run Code Online (Sandbox Code Playgroud)

然后使用coroutine.wrap创建一个函数,为您的生成器创建一个协程,并在每次调用该函数时恢复它.

function grandChildren(t)
    return coroutine.wrap(function() eachGrandChild(t) end)
end
Run Code Online (Sandbox Code Playgroud)

现在你有了你的迭代器:

for key, val in grandChildren(root) do
    print(key, val)
end
Run Code Online (Sandbox Code Playgroud)

在Lua编程中有一章.