Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JavaScript - Generating combinations from n arrays with m elements [duplicate]

I'm having trouble coming up with code to generate combinations from n number of arrays with m number of elements in them, in JavaScript. I've seen similar questions about this for other languages, but the answers incorporate syntactic or library magic that I'm unsure how to translate.

Consider this data:

[[0,1], [0,1,2,3], [0,1,2]] 

3 arrays, with a different number of elements in them. What I want to do is get all combinations by combining an item from each array.

For example:

0,0,0 // item 0 from array 0, item 0 from array 1, item 0 from array 2 0,0,1 0,0,2 0,1,0 0,1,1 0,1,2 0,2,0 0,2,1 0,2,2 

And so on.

If the number of arrays were fixed, it would be easy to make a hard coded implementation. But the number of arrays may vary:

[[0,1], [0,1]] [[0,1,3,4], [0,1], [0], [0,1]] 

Any help would be much appreciated.

like image 368
quano Avatar asked Mar 08 '13 16:03

quano


2 Answers

Here is a quite simple and short one using a recursive helper function:

function cartesian(...args) {     var r = [], max = args.length-1;     function helper(arr, i) {         for (var j=0, l=args[i].length; j<l; j++) {             var a = arr.slice(0); // clone arr             a.push(args[i][j]);             if (i==max)                 r.push(a);             else                 helper(a, i+1);         }     }     helper([], 0);     return r; } 

Usage:

cartesian([0,1], [0,1,2,3], [0,1,2]); 

To make the function take an array of arrays, just change the signature to function cartesian(args) instead of using rest parameter syntax.

like image 80
Bergi Avatar answered Sep 24 '22 21:09

Bergi


You could take an iterative approach by building sub arrays.

var parts = [[0, 1], [0, 1, 2, 3], [0, 1, 2]],      result = parts.reduce((a, b) => a.reduce((r, v) => r.concat(b.map(w => [].concat(v, w))), []));    console.log(result.map(a => a.join(', ')));
.as-console-wrapper { max-height: 100% !important; top: 0; }
like image 41
Nina Scholz Avatar answered Sep 22 '22 21:09

Nina Scholz