1

I need some help on how to loop through this array of variable array sizes.

var x = [[1,2,3],[8],[10,11,12],[13]];

What I want the result to be in an array with the combinations.

y = [[1,8,10,13],[2,8,10,13],[3,8,10,13]
,[1,8,11,13],[2,8,11,13],[3,8,11,13]....]

I hope this makes sense what I want to do.

for(var i=0; i<x.length; i++)
{
    for(var ii=0; x[i].length; ii++)
    {
        //At this point I have x[0], but each number needs to be part of a compination 
    }
}

What I ultimately want to do is take set of lists (amount of lists set by the user) and make a combination across the lists. Example 4 lists below.

1 5  8  12
2 6  11
3 9
4 10
4
  • 4
    so x[i][ii] .... Commented May 18, 2017 at 21:38
  • Yes x[0][0] is the first item in element y[0] and x[0][1] is the first element in y[1] Commented May 18, 2017 at 21:42
  • so loop and push.... Commented May 18, 2017 at 21:43
  • I don't know how to set the loop up, the second loop will loop through all the items in x[0]. I just want the first item and loop through the rest of the items in x. Actually, I need to treat each index of X as a list of items, then do a combination of all items across x, not within an index of x. Commented May 18, 2017 at 21:44

2 Answers 2

4

This looks like cartesian product and you can use recursion with one for loop to do this.

var x = [[1,2,3],[8],[10,11,12],[13]];

function cartesian(data) {
  var result = [];

  function generate(data, n, c) {
    if (n == data.length) {
      result.push(c.slice())
      return;
    }

    for (var i = 0; i < data[n].length; i++) {
      c[n] = data[n][i];
      generate(data, n + 1, c);
    }
  }

  generate(data, 0, [])
  return result
}

console.log(JSON.stringify(cartesian(x)))

Sign up to request clarification or add additional context in comments.

2 Comments

Very useful. Thank you soo much!
is function generate tail-recursive one ? I am not sure since it is called inside loop
0
function makeCombo(x, pickFrom, soFar) {

    if (pickFrom == x.length ) {
        console.log(soFar);
        return;
    }

    for (var option = 0 ; option < x[pickFrom].length ; ++option) {
        soFar.push(x[pickFrom][option]);
        makeCombo(x, pickFrom+1, soFar);
        soFar.pop();
    }
}

makeCombo([[1,2,3],[8],[10,11,12],[13]], 0, []);

Output :

[ 1, 8, 10, 13 ]
[ 1, 8, 11, 13 ]
[ 1, 8, 12, 13 ]
[ 2, 8, 10, 13 ]
[ 2, 8, 11, 13 ]
[ 2, 8, 12, 13 ]
[ 3, 8, 10, 13 ]
[ 3, 8, 11, 13 ]
[ 3, 8, 12, 13 ]

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.