“转置/压缩”功能未按预期工作
我正在尝试使用 Lua 中的函数 mapn 和 zip 构建一个优雅的转置函数。
mapn 和 zip 如下(来自 lua 书):
function map(func, array)
local new_array = {}
for i,v in ipairs(array) do
new_array[i] = func(v)
end
return new_array
end
function mapn(func, ...)
local new_array = {}
local i=1
local arg_length = table.getn(arg)
while true do
local arg_list = map(function(arr) return arr[i] end, arg)
if table.getn(arg_list) < arg_length then return new_array end
new_array[i] = func(unpack(arg_list))
i = i+1
end
end
这些按预期工作。
然后,我将 zip 和 transpose 定义为:
function zip(...)
return mapn(function(...) return {...} end,...)
end
function transpose(...)
return zip(unpack(...))
end
现在 transpose({{1,2},{3,4},{5,6}}) 生成 {{1,3,5},{2,4,6}} 为预期的。
但 transpose({{1,2},{3,4},{5}}) 不会生成 {{1,3,5},{2,4}}。它只产生一行。
我怎样才能让它产生我想要的结果?
我只是决定写一个“不优雅”的函数。似乎没有顺利使用mapn和friends的方法。
function transp(L)
local n=#L
local m,M=1e42,0
--Get the beginning and end of resultant transpose list.
for i=1,n do
for k,v in pairs(L[i]) do
if M<k then M=k end
if m>k then m=k end
end
end
local nt={}
for i=m,M do
local rt={}
for j=1,n do
rt[j]=L[j][i]
end
table.insert(nt,rt)
end
return nt
end
请批评并改进这个候选解决方案。
I am trying to build an elegant transpose function using functions mapn and zip in Lua.
The mapn and zip are as follows (From the lua book):
function map(func, array)
local new_array = {}
for i,v in ipairs(array) do
new_array[i] = func(v)
end
return new_array
end
function mapn(func, ...)
local new_array = {}
local i=1
local arg_length = table.getn(arg)
while true do
local arg_list = map(function(arr) return arr[i] end, arg)
if table.getn(arg_list) < arg_length then return new_array end
new_array[i] = func(unpack(arg_list))
i = i+1
end
end
These work as expected.
I then define zip and transpose as:
function zip(...)
return mapn(function(...) return {...} end,...)
end
function transpose(...)
return zip(unpack(...))
end
Now transpose({{1,2},{3,4},{5,6}}) produces {{1,3,5},{2,4,6}} as expected.
But transpose({{1,2},{3,4},{5}}) does not produce {{1,3,5},{2,4}}. It only produces one row.
How can I get it to produce the result I wish for?
I just decided to write an "inelegant" function instead. It seems there's no smooth way to use mapn and friends.
function transp(L)
local n=#L
local m,M=1e42,0
--Get the beginning and end of resultant transpose list.
for i=1,n do
for k,v in pairs(L[i]) do
if M<k then M=k end
if m>k then m=k end
end
end
local nt={}
for i=m,M do
local rt={}
for j=1,n do
rt[j]=L[j][i]
end
table.insert(nt,rt)
end
return nt
end
Please critique and improve this candidate solution.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我修复了您的代码中的一些问题,我认为它现在可以按预期工作,我已经添加了内联注释。
使用示例:
I fixed a few things in your code and I think it works now as intended, I've added comments inline.
Usage example:
由于这一行,示例中的
{5}
被忽略:您可能想要做的是仅当
arg_list
为空时才跳出循环。如果行的长度单调增加,这将给出您想要的结果。
对于更一般的情况,后面的行可能比前面的行短
(例如
{{1,2},{3,4,5},{6}}
),您需要跟踪行长度以允许存在孔。这可以通过向map
添加可选参数(和额外的返回值)来指示func(array[i])< 的最大索引
i
来完成。 /code> 被评估:The
{5}
in your example is being ignored because of this line:What you may want to do instead is break out of the loop only when
arg_list
is empty.This will then give the result you want provided that the rows are monotonically increasing in length.
For the more general case, when later rows may be shorter than earlier ones
(e.g.
{{1,2},{3,4,5},{6}}
), you will need to keep track of the row lengths to allow for holes. This can be done by adding an optional argument (and extra return value) tomap
to indicate the maximum indexi
for whichfunc(array[i])
was evaluated: