multidimensional-array - Lua - 编写类似于 ipairs 的迭代器,但选择索引

标签 multidimensional-array lua iterator

我想编写一个行为与 ipairs 完全相同的迭代器,除了它需要第二个参数。第二个参数是 ipairs 应该循环的索引表。

我想知道我目前的方法是否效率低下,以及如何通过闭包来改进它。

我也愿意接受其他方法来完成同样的事情。但我喜欢迭代器,因为它们易于使用和调试。

我将引用并使用 Programming in Lua 中的一些术语(PiL),尤其是关于闭包的章节(链接中的第 7 章)。


所以我想要这个,

ary = {10,20,30,40}

for i,v in selpairs(ary, {1,3}) do
    ary[i] = v+5
    print(string.format("ary[%d] is now = %g", i, ary[i]))
end

这会输出这个:

ary[1] is now = 15
ary[3] is now = 35

我目前的方法是这样的:(按顺序:迭代器、工厂,然后是泛型)

iter = function (t, s)
    s = s + 1   
    local i = t.sel[s]
    local v = t.ary[i]

    if v then 
        return s, i, v
    end
end

function selpairs (ary, sel)
    local t = {}
    t.ary = ary
    t.sel = sel

    return iter, t, 0
end

ary = {10,20,30,40}
for _,i,v in selpairs(ary, {1,3}) do
    ary[i] = v+5
    print(string.format("ary[%d] is now = %g", i, ary[i]))
end

-- same output as before

它有效。 sel 是“选定”索引的数组。 ary 是您要对其执行循环的数组。在 iter 中,s 索引 seli 索引 ary

但是有一些明显的问题。

  • 我必须始终丢弃第一个返回的参数 s(for 循环中的 _)。我从不需要 s,但它必须作为第一个参数返回,因为它是“控制变量”。
  • “不变状态”实际上是打包到一个表中的两个不变状态(arysel)。 Pil 说这更昂贵,并建议使用闭包。 (因此我写了这个问题)。

其余的可以忽略。我只是为我想使用 selpairs 的目的提供更多上下文。

我主要关心第二个问题。我正在为我正在制作音乐的图书馆写这篇文章。执行像 ary[i] = v+5 这样简单的事情并不是真正的问题。但是,当我执行诸如访问对象属性和检查边界之类的操作时,我担心“作为表的不变状态”方法可能会产生不必要的开销。我应该担心这个吗?

如果有的话,我想知道如何用闭包来写这个只是为了知识。

当然,我尝试过使用闭包,但我无法理解“封闭函数中的局部变量”的范围以及它与调用迭代器的 for 循环的关系。


至于第一个问题,我想我可以使控制变量成为一个包含siv 的表。在 iter 的返回处,以所需的顺序解压表。 但我猜这也是低效的。


最终,我想编写一个迭代器来执行此操作,但嵌套到自身中除外。我的主要数据结构是数组的数组,所以我希望做这样的事情:

ary_of_arys = {
    {10,  20, 30,  40},
    {5,   6,  7,   8},
    {0.9, 1,  1.1, 1.2},
}

for aoa,i,v in selpairs_inarrays(ary_of_arys, {1,3}, {2,3,4}) do
    ary_of_arys[aoa][i] = v+5
end

这也可以使用表方法,但最好知道如何利用闭包。

我实际上做过类似的事情:一个函数基本上通过将函数作为第四个也是最后一个参数来做同样的事情。它工作得很好,但这会比迭代器效率低吗?

最佳答案

您可以在上值中隐藏“控制变量”:

local function selpairs(ary, sel)
   local s = 0
   return
      function()
         s = s + 1
         local i = sel[s]
         local v = ary[i]
         if v then
            return i, v
         end
      end
end

用法:

local ary = {10,20,30,40}

for i, v in selpairs(ary, {1,3}) do
   ary[i] = v+5
   print(string.format("ary[%d] is now = %g", i, ary[i]))
end

嵌套用法:

local ary_of_arys = {
   {10,  20, 30,  40},
   {5,   6,  7,   8},
   {0.9, 1,  1.1, 1.2},
}
local outer_indices = {1,3}
local inner_indices = {2,3,4}

for aoa, ary in selpairs(ary_of_arys, outer_indices) do
   for i, v in selpairs(ary, inner_indices) do
      ary[i] = v+5  -- This is the same as  ary_of_arys[aoa][i] = v+5
   end
end

关于multidimensional-array - Lua - 编写类似于 ipairs 的迭代器,但选择索引,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47780790/

相关文章:

php - 重新排列数组以合并重叠结果

java - Java 中数组初始值设定项内带有尾随逗号的数组

java 多维数组失败并出现空指针异常

php - 嵌入式服务器的 Web 技术

scripting - 电晕SDK : iPhone 5 adjustment

python - 如果未使用特定迭代器,类似 zip 的函数将失败

javascript - HTML 中的 AJAX POST 方法

c++ - 如何将 C++ 嵌套类注册到 Lua

java - 每次遍历列表时创建一个新的迭代器对象

c++ - 为什么在达到容量后在 vector 中完成插入时 C++ 不处理迭代器?