Search for each combination of elements in a table (Lua / PseudoCode)

I am trying to execute a function with every combination of elements from a table. (In Lua). The table and elements may change, but the structure will remain unchanged. The table is organized so that [1] of them is the first argument of the function, etc. Etc.

If this is the table that I have,

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

If I wrote this manually, it probably would have looked like this: (Given that the function is called Exe).

 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) 

However, I DO NOT WANT to write this, and this violates my general rule: if you copy and paste into a program, you are doing it wrong.

So instead, I would like to go through the table and do every possible combination. The problem is that a table can (potentially) have any number of tables inside it, and also that a table inside a table can potentially have an unlimited number of values.

For example, a table might look like this:

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

As a result, the execution will look like this:

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

In addition, the table may end as follows:

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

In which the exeuction will end, like ..

 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) 

As you can see, I found a pattern ... I was able to split the above β€œexecution” above into segments / groups such as line 1 and line 2 have one change. They are then copied to lines 4 and 5, but the next variable is changed.

As you can see, it's hard for me to put this template in code. I think some recursion function will be required, but I'm not sure how to remove it or go through it. I think I will have to use functions with ... as arguments and an unpack function, but I'm not sure how this will work.

In addition, the reason why this is required, and not just manual copying and pasting (which would actually be easier), is because the contents of the table will be generated.

Can you guys help me?

+7
source share
1 answer

Use recursion.

Imagine a map_all (fcn, tab, idx, ...) function map_all (fcn, tab, idx, ...) that maps fcn to the product of the elements of all tables tab[1] to tab[idx] added to ...

The main case is when idx less than 1. In this case, just use fcn(...)

Otherwise map_all(fcn, tab, idx-1, <el>, ...) for all <el> in 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 

So,

 > 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 

and

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

and

 > 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 > 
+7
source

All Articles