[Closed] Getting all combinations of a set of arrays
Hi…
I have a number of arrays and I want to return an array with every combination of the values in the arrays.
So I might have:
x=#(“1”, “2”, “3”)
y=#(“a”, “b”, “c”, “d”)
z=#(“y”, “z”)
arr = #(x, y, z)
and I want to return
#(#(“1”, “a”, “y”), #(“1”, “a”, “z”), #(“1”, “b”, “y”), #(“1”, “b”, “z”), #(“1”, “c”, “y”)…#(“3”, “d”, “z”))
The amount of arrays in arr is variable as is the number of elements in all arrays
Its doing my head in! :banghead:
Any Ideas?
something like this?
x=#("1", "2", "3")
y=#("a", "b", "c", "d")
z=#("y", "z")
combArr = #()
for i = 1 to x.count do
(
for j = 1 to y.count do
(
for k = 1 to z.count do
(
local tmparr = #(x[i],y[j],z[k])
append combArr tmparr
)
)
)
This can be simplified to
x=#("1", "2", "3")
y=#("a", "b", "c", "d")
z=#("y", "z")
combArr = #()
for i in x do for j in y do for k in z do append combArr #(i,j,k)
combArr
Yep something like that… but it wont dynamically work for
w=#(“9”, “8”)
x=#(“1”, “2”, “3”)
y=#(“a”, “b”, “c”, “d”)
z=#(“y”, “z”)
or just
y=#(“a”, “b”, “c”, “d”)
z=#(“y”, “z”)
The amount of arrays is no set unfortunatley, and this is my problem!
This is what I have at the moment… doesnt quite work
x=#("1", "2", "3")
y=#("a", "b", "c", "d")
z=#("y", "z")
arr = #(x, y, z)
count = 1
manArr = #(arr.count) --management array - adding arrayIndexTracker
finalArr=#()
clearlistener()
for i = 1 to arr.count do
(
count = count*arr[1].count
append manArr #(1, i, arr[i].count) --add #(arrayItemTracker, arrayIndex, arrayCount) to management array per array
)
print count
print (manArr as string)
for i = 1 to count do
(
MyVal=#()
for x = 1 to arr.count do
(
append MyVal arr[manarr[x+1][2]][manarr[x+1][1]]
)
append finalArr MyVal
if manarr[manArr[1]+1][1]==manarr[manArr[1]+1][3] then --if at the end of arrayCount reset arrayItemTracker
(
manarr[manArr[1]+1][1] = 1
manArr[1] -=1
)
else manarr[manArr[1]+1][1] += 1
)
print finalArr
/*
Here is my take on it.
In short, I create a management array that contains counters that start at 1 and reach the max. number of iterations each, just like a digital clock, with the right most element incrementing fastest and the one to the left incrementing once each time the right one warps around to 1. We also know how many elements we expect, so we do not have to loop forever, only until we have the expected number of combinations.
The rest works just like a bunch of nested for loops, but since we store the variables of the “loops” in an array, we can nest ANY number of them without actually creating for loops. We just let the “digital clock” tick and we collect the elements the “clock” is pointing at…
(
--this is a recursive function to increase the counter(s) in the indexArr array
fn increaseCounter indexArr theArray theIndex =
(
indexArr[theIndex] += 1 --increase the indexed element by 1
if indexArr[theIndex] > theArray[theIndex].count do --if it is higher than the number of sub-array elements
(
indexArr[theIndex]=1 --warp back to one
if theIndex > 1 do --and if not the left most element,
increaseCounter indexArr theArray (theIndex-1) --increase the counter to the left
)--end if
)--end fn
fn getArrayCombinations theArray =
(
local indexArr = for i in theArray collect 1 --collect 1 for each entry in arr
local combArr = #() --here we will collect the results
maxNumber = 1 --this will store the number of elements we expect
for i in theArray do maxNumber *= i.count --we multiply the counts of all sub-arrays
while combArr.count < maxNumber do --as long as we are below that expected number,
(
--collect all elements based on the counter array
append combArr (for i = 1 to theArray.count collect theArray[i][indexArr[i]])
increaseCounter indexArr theArray theArray.count --then increase the right-most counter
)--end while
print combArr --print the result
OK
)
--define some arrays
x=#("1", "2", "3")
y=#("a", "b", "c", "d")
z=#("y", "z")
getArrayCombinations #(x, y, z) --can be ANY number of sub-arrays
)
Thats it! Thanks Bobo! I had the right idea but not the 1337 scripting skillz to do it!
Thanks mate!