2

Я хочу, чтобы иметь возможность сопоставить функции, которые принимают множество аргументов каккарта переменной длины функции Lua

function(a, b) return a+b end 

на стол так, что я могу писать такие вещи, как

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

, но я не устраивает Lua переменной длиной и code samples на Викиучебниках использовать table.getn, и при замене их # он не работает и возвращает «attempt to preform arithmatic on local 'a' (a nil value)»

+0

Пожалуйста, не оставляйте вопросы без принятого ответа. Вы отправили это в течение недели назад и получили 3 ответа с тех пор. Принятые ответы помогают будущим пользователям быстрее решать свою проблему, а также вознаграждает человека, который вам больше всего помог. Если ни один из 3 ответов не помог, возможно, больше подчеркнуть вашу проблему. – warspyking

ответ

1

Еще одна возможность:

local unpack = table.unpack or unpack 

-------------------------------------------------------------------------------- 
-- Python-like zip() iterator 
-------------------------------------------------------------------------------- 

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','Function expected for 1st arg') 
    local t = {...} 
    return coroutine.wrap(
     function() 
      for t in zip(unpack(t)) do 
      coroutine.yield(f(unpack(t))) 
      end 
     end) 
end 

-------------------------------------------------------------------------------- 
-- Example use 

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 
0

Возможно, вы ищете что-то вроде этого:

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 
0
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})