Lua中的可变参数函数map

我想要能够将需要多个参数的函数映射到一个表上,例如

    function(a, b) return a+b end

这样我就可以像这样写代码

    answer = varmap(function(a, b) return a+b end, {1, 7, 3}, {5, 4, 8}

但是我不熟悉lua的可变参数和wikibooks上的代码示例使用table.getn,如果将其替换为#,它不起作用并且返回"尝试在局部变量'a'(一个nil值)上进行算术运算"

点赞
用户6879826
用户6879826

也许您正在寻找类似于这样的东西:

function varmapn(func, ...)
   local args, result = { ... }, {}
   for arg_i = 1, #(args[1]) do
      local call_args = {}
      for arg_list = 1, #args do
         table.insert(call_args, args[arg_list][arg_i])
      end
      table.insert(result, func(table.unpack(call_args)))
   end
   return result
end

示例交互:

> answer = varmapn(function (a, b) return a+b end, {1, 7, 3}, {5, 4, 8})
> print(answer)
table: 0x970eb0
> for i = 1, 3 do print(answer[i]) end
6
11
11

或者,这是一个更普遍的稍微复杂一些的函数,对于参数列表,它接受数组,或者它接受带有任意键的表:

function mapn(func, ...)
   local args, call_args = { ... }, {}
   local result = {}

   for k in pairs(args[1]) do
      call_args[k] = {}
   end

   for arg_list, v in pairs(args) do
      for k in pairs(args[1]) do
         table.insert(call_args[k], v[k])
      end
   end
   for k, v in pairs(call_args) do
      result[k] = func(table.unpack(v))
   end
   return result
end

示例交互:

> answer = mapn(function (a, b) return a+b end, {x=1, y=7, z=3}, {x=5, y=4, z=8})
> for k,v in pairs(answer) do print(k .. " = " .. v) end
z = 11
y = 11
x = 6
> answer = mapn(function (a, b) return a+b end, {1, 7, 3}, {5, 4, 8})
> for i = 1, 3 do print(answer[i]) end
6
11
11
2017-02-02 18:02:56
用户6834680
用户6834680
local function imap(func, ...)  -- imap(func, src_table_1, src_table_2, ...)
   local result = {}
   local src_tables_arr = {...}
   if #src_tables_arr == 1 then
      for k, v in ipairs(src_tables_arr[1]) do
         result[k] = func(v)
      end
   else
      for k = 1, #src_tables_arr[1] do
         result[k] = func(
                             (table.unpack or unpack)
                             (
                                imap(
                                   function(src_t) return src_t[k] end,
                                   src_tables_arr
                                )
                             )
                         )
      end
   end
   return result
end
table.imap = imap

用法:

local arr = table.imap(function (a, b) return a+b end, {1, 7, 3}, {5, 4, 8})
2017-02-02 18:09:33
用户3735873
用户3735873
一个更多可能性的例子:

local unpack = table.unpack or unpack


-- 类似于 Python 的 zip() 迭代器

function zip(...) local arrays, ans = {...}, {} local index = 0 return function() index = index + 1 for i,t in ipairs(arrays) do if type(t) == 'function' then ans[i] = t() else ans[i] = t[index] end if ans[i] == nil then return end end return ans end end


function map(f,...) assert(type(f) == 'function','1st arg 需要是一个函数') local t = {...} return coroutine.wrap( function() for t in zip(unpack(t)) do coroutine.yield(f(unpack(t))) end end) end


-- 用例子演示

for item in map(function(a, b) return a+b end, {1, 7, 3}, {5, 4, 8}) do print(item) end

print()

for item in map(function(a) return a*2 end, {1, 7, 3}) do print(item) end

```

2017-02-02 20:12:48