Поиск каждой комбинации элементов в таблице (Lua / псевдокод)

Я пытаюсь выполнить функцию с каждой комбинацией элементов из таблицы. (в Lua.) Таблица и элементы могут меняться, но структура останется прежней. Таблица организована так, что [1] это было бы первым аргументом функции, и так далее и так далее.

если это стол, который у меня есть,

Table = {
    [1] = {Player1, Player2}
    [2] = {PlayerA, PlayerB, PlayerC}
    [3] = {PlayerOne, PlayerTwo}
}

если бы я написал это вручную, это, вероятно, выглядело бы так: (учитывая, что функция называется Исполняемый.)

Exe(Player1, PlayerA, PlayerOne)
Exe(Player2, PlayerA, PlayerOne)
Exe(Player3, PlayerA, PlayerOne)

Exe(Player1, PlayerB, PlayerOne)
Exe(Player2, PlayerB, PlayerOne)
Exe(Player3, PlayerB, PlayerOne)

Exe(Player1, PlayerC, PlayerOne)
Exe(Player2, PlayerC, PlayerOne)
Exe(Player3, PlayerC, PlayerOne)


Exe(Player1, PlayerA, PlayerTwo)
Exe(Player2, PlayerA, PlayerTwo)
Exe(Player3, PlayerA, PlayerTwo)

Exe(Player1, PlayerB, PlayerTwo)
Exe(Player2, PlayerB, PlayerTwo)
Exe(Player3, PlayerB, PlayerTwo)

Exe(Player1, PlayerC, PlayerTwo)
Exe(Player2, PlayerC, PlayerTwo)
Exe(Player3, PlayerC, PlayerTwo)

вместо этого, я хотел бы пройти через стол и выполнить каждую возможную комбинацию. Проблема в том, что таблица может (потенциально) иметь любое количество таблиц внутри нее, а также что таблица внутри таблицы потенциально может иметь неограниченное количество значений.

например, таблица может выглядеть так:

Table = {
    [1] = {Player1, Player2}
    [2] = {PlayerA}
    [3] = {PlayerOne}
}

в котором выполнение будет выглядеть так вручную:

Exe(Player1, PlayerA, PlayerOne)
Exe(Player2, PlayerA, PlayerOne)

кроме того, таблица может закончиться такой:

Table = {
    [1] = {Player1, Player2}
    [2] = {PlayerA}
    [3] = {PlayerOne}
    [4] = {PlayerUno, PlayerDos}
    [5] = {PlayerApple, PlayerBoy, PlayerCat, PlayerDog}
}

, в котором выполнение запроса закончится..

Exe(Player1, PlayerA, PlayerOne, PlayerUno, PlayerApple)
Exe(Player2, PlayerA, PlayerOne, PlayerUno, PlayerApple)

Exe(Player1, PlayerA, PlayerOne, PlayerDos, PlayerApple)
Exe(Player2, PlayerA, PlayerOne, PlayerDos, PlayerApple)


Exe(Player1, PlayerA, PlayerOne, PlayerUno, PlayerBoy)
Exe(Player2, PlayerA, PlayerOne, PlayerUno, PlayerBoy)

Exe(Player1, PlayerA, PlayerOne, PlayerDos, PlayerBoy)
Exe(Player2, PlayerA, PlayerOne, PlayerDos, PlayerBoy)


Exe(Player1, PlayerA, PlayerOne, PlayerUno, PlayerCat)
Exe(Player2, PlayerA, PlayerOne, PlayerUno, PlayerCat)

Exe(Player1, PlayerA, PlayerOne, PlayerDos, PlayerCat)
Exe(Player2, PlayerA, PlayerOne, PlayerDos, PlayerCat)


Exe(Player1, PlayerA, PlayerOne, PlayerUno, PlayerDog)
Exe(Player2, PlayerA, PlayerOne, PlayerUno, PlayerDog)

Exe(Player1, PlayerA, PlayerOne, PlayerDos, PlayerDog)
Exe(Player2, PlayerA, PlayerOne, PlayerDos, PlayerDog)

как вы можете видеть, я нашел закономерность... Я смог разделить вышеупомянутую "выполнение" выше на сегменты / группы, такие как строка 1 и строка 2 имеют одно изменение. Затем, они копируются в строки 4 и 5, но следующая переменная get изменяется.

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

кроме того, почему это необходимо, а не просто вручную копировать и вставка его (что на самом деле было бы проще), потому что содержимое таблицы будет сгенерировано.

вы можете мне помочь?

1 ответов


использовать рекурсию.

представим функцию map_all (fcn, tab, idx, ...) что карты fcn к произведению элементов всех таблиц tab[1] to tab[idx] перед ...

базовый случай, когда idx меньше 1. В этом случае, просто используйте fcn(...)

иначе map_all(fcn, tab, idx-1, <el>, ...) для всех <el> на tab[idx]

function map_all (fcn, tab, idx, ...)
    if idx < 1 then
        fcn(...)
    else
        local t = tab[idx]
        for i = 1, #t do map_all(fcn, tab, idx-1, t[i], ...) end
    end
end

и

> Table = {
>>     [1] = {'Player1', 'Player2'},
>>     [2] = {'PlayerA', 'PlayerB', 'PlayerC'},
>>     [3] = {'PlayerOne', 'PlayerTwo'}
>> }
> map_all(print, Table, #Table)
Player1 PlayerA PlayerOne
Player2 PlayerA PlayerOne
Player1 PlayerB PlayerOne
Player2 PlayerB PlayerOne
Player1 PlayerC PlayerOne
Player2 PlayerC PlayerOne
Player1 PlayerA PlayerTwo
Player2 PlayerA PlayerTwo
Player1 PlayerB PlayerTwo
Player2 PlayerB PlayerTwo
Player1 PlayerC PlayerTwo
Player2 PlayerC PlayerTwo

и

> Table = {
>>     [1] = {'Player1', 'Player2'},
>>     [2] = {'PlayerA'},
>>     [3] = {'PlayerOne'}
>> }
> map_all(print, Table, #Table)
Player1 PlayerA PlayerOne
Player2 PlayerA PlayerOne

и

> Table = {
>>     [1] = {'Player1', 'Player2'},
>>     [2] = {'PlayerA'},
>>     [3] = {'PlayerOne'},
>>     [4] = {'PlayerUno', 'PlayerDos'},
>>     [5] = {'PlayerApple', 'PlayerBoy', 'PlayerCat', 'PlayerDog'},
>> }
> map_all(print, Table, #Table)
Player1 PlayerA PlayerOne   PlayerUno   PlayerApple
Player2 PlayerA PlayerOne   PlayerUno   PlayerApple
Player1 PlayerA PlayerOne   PlayerDos   PlayerApple
Player2 PlayerA PlayerOne   PlayerDos   PlayerApple
Player1 PlayerA PlayerOne   PlayerUno   PlayerBoy
Player2 PlayerA PlayerOne   PlayerUno   PlayerBoy
Player1 PlayerA PlayerOne   PlayerDos   PlayerBoy
Player2 PlayerA PlayerOne   PlayerDos   PlayerBoy
Player1 PlayerA PlayerOne   PlayerUno   PlayerCat
Player2 PlayerA PlayerOne   PlayerUno   PlayerCat
Player1 PlayerA PlayerOne   PlayerDos   PlayerCat
Player2 PlayerA PlayerOne   PlayerDos   PlayerCat
Player1 PlayerA PlayerOne   PlayerUno   PlayerDog
Player2 PlayerA PlayerOne   PlayerUno   PlayerDog
Player1 PlayerA PlayerOne   PlayerDos   PlayerDog
Player2 PlayerA PlayerOne   PlayerDos   PlayerDog
>