首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >"Transpose/Zip“函数未按预期工作

"Transpose/Zip“函数未按预期工作
EN

Stack Overflow用户
提问于 2011-11-08 04:36:37
回答 2查看 853关注 0票数 0

我正在使用Lua中的mapn和zip函数构建一个优雅的转置函数。

mapn和zip如下(来自lua书):

代码语言:javascript
复制
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定义为:

代码语言:javascript
复制
function zip(...)
  return mapn(function(...) return {...} end,...)
end

function transpose(...)
  return zip(unpack(...))
end

现在转置({1,2},{3,4},{5,6}})产生{1,3,5},{2,4,6}。

但是转座子({1,2},{3,4},{5})不产生{1,3,5},{2,4}。它只产生一行。

我怎样才能得到我想要的结果呢?

我只是决定写一个“不雅”的函数代替。似乎没有顺利的方法使用地图和朋友。

代码语言:javascript
复制
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

请评论并改进此候选解决方案。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2011-11-08 15:15:34

我在您的代码中修正了一些东西,我认为它现在按预期工作了,我已经在行中添加了注释。

代码语言:javascript
复制
function map(func, array)
  local new_array = {}
  for i, v in ipairs(array) do
    new_array[#new_array + 1] = func(v)
  end 
  return new_array
end

function mapn(func, ...)
  -- Variadic arguments bound to an array.
  local arrays = {...}
  local new_array = {}
  -- Simple for-loop.
  local i = 1 
  while true do
    local arg_list = map(function(arr) return arr[i] end, arrays)
    if #arg_list == 0 then
      break
    end 
    new_array[i] = func(unpack(arg_list))
    i = i + 1 
  end 
  return new_array
end


-- Using 'mapn' instead of 'map' (probably how you intended).
function zip(...)
  return mapn(function(...) return {...} end,...)
end

-- Same as before.
function transpose(...)
  return zip(unpack(...))
end

用法示例:

代码语言:javascript
复制
for _, row in pairs(transpose({{1,2},{3,4},{5}})) do
  for _, col in pairs(row) do io.write(col .. ' ') end
  io.write('\n')
end
-- Output: 1 3 5 
--         2 4
票数 3
EN

Stack Overflow用户

发布于 2011-11-08 18:46:45

您的示例中的{5}正被忽略,因为这一行:

代码语言:javascript
复制
if table.getn(arg_list) < arg_length then return new_array end

相反,您可能要做的是,只有在arg_list为空时才能脱离循环。

这将给出您想要的结果,前提是行的长度是单调增长的。

在更一般的情况下,以后的行可能比前面的行短。

(例如,{{1,2},{3,4,5},{6}}),您将需要跟踪行的长度,以允许孔。这可以通过向map添加一个可选参数(和额外的返回值)来实现,以指示计算func(array[i])的最大索引i

代码语言:javascript
复制
function map(func, array, len)
 local new_array = {}
 len = len or #array
 for i=1,len do
   new_array[i] = func(array[i])
 end
 return new_array, len
end

function mapn(func, ...)
 local new_array = {}
 local i=1
 local arg_length = select('#', ...)
 local args = {...}
 while true do
   local arg_list, num_results = map(function(arr) return arr[i] end, args, arg_length)
   if not next(arg_list) then return new_array end
   new_array[i] = func(unpack(arg_list, 1, num_results))
   i = i+1
 end
end

function zip(...)
  return mapn(function(...) return {...} end,...)
end

function transpose(...)
  return zip(unpack(...))
end
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8046009

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档