我想编写一个行为与 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
索引 sel
,i
索引 ary
。
但是有一些明显的问题。
- 我必须始终丢弃第一个返回的参数
s
(for 循环中的_
)。我从不需要s
,但它必须作为第一个参数返回,因为它是“控制变量”。 - “不变状态”实际上是打包到一个表中的两个不变状态(
ary
和sel
)。 Pil 说这更昂贵,并建议使用闭包。 (因此我写了这个问题)。
其余的可以忽略。我只是为我想使用 selpairs
的目的提供更多上下文。
我主要关心第二个问题。我正在为我正在制作音乐的图书馆写这篇文章。执行像 ary[i] = v+5
这样简单的事情并不是真正的问题。但是,当我执行诸如访问对象属性和检查边界之类的操作时,我担心“作为表的不变状态”方法可能会产生不必要的开销。我应该担心这个吗?
如果有的话,我想知道如何用闭包来写这个只是为了知识。
当然,我尝试过使用闭包,但我无法理解“封闭函数中的局部变量”的范围以及它与调用迭代器的 for
循环的关系。
至于第一个问题,我想我可以使控制变量成为一个包含s
、i
和v
的表。在 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/