Article Categories
- All Categories
-
Data Structure
-
Networking
-
RDBMS
-
Operating System
-
Java
-
MS Excel
-
iOS
-
HTML
-
CSS
-
Android
-
Python
-
C Programming
-
C++
-
C#
-
MongoDB
-
MySQL
-
Javascript
-
PHP
-
Economics & Finance
Generating combinations from n arrays with m elements in JavaScript
We are required to write a JavaScript function that generates combinations from n number of arrays with m number of elements in them.
For example, consider this data:
const arr = [ [0,1], [0,1,2,3], [0,1,2] ]
We have 3 sub-arrays with different numbers of elements. What we want to do is get all combinations by selecting one item from each array.
Understanding the Problem
The goal is to generate a Cartesian product of multiple arrays. For the example above, we want combinations like:
[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:
const arr1 = [[0,1], [0,1]]; const arr2 = [[0,1,3,4], [0,1], [0], [0,1]];
Solution Using Recursive Approach
Here's a recursive solution that works for any number of arrays:
const arr = [
[0,1],
[0,1,2,3],
[0,1,2]
];
const combineAll = (array) => {
const res = [];
let max = array.length - 1;
const helper = (arr, i) => {
for (let j = 0, l = array[i].length; j < l; j++) {
let copy = arr.slice(0);
copy.push(array[i][j]);
if (i == max)
res.push(copy);
else
helper(copy, i + 1);
}
};
helper([], 0);
return res;
};
console.log(combineAll(arr));
[ [ 0, 0, 0 ], [ 0, 0, 1 ], [ 0, 0, 2 ], [ 0, 1, 0 ], [ 0, 1, 1 ], [ 0, 1, 2 ], [ 0, 2, 0 ], [ 0, 2, 1 ], [ 0, 2, 2 ], [ 0, 3, 0 ], [ 0, 3, 1 ], [ 0, 3, 2 ], [ 1, 0, 0 ], [ 1, 0, 1 ], [ 1, 0, 2 ], [ 1, 1, 0 ], [ 1, 1, 1 ], [ 1, 1, 2 ], [ 1, 2, 0 ], [ 1, 2, 1 ], [ 1, 2, 2 ], [ 1, 3, 0 ], [ 1, 3, 1 ], [ 1, 3, 2 ] ]
Alternative Iterative Approach
Here's an iterative solution using the reduce method:
const arr = [
[0,1],
[0,1,2,3],
[0,1,2]
];
const cartesianProduct = (arrays) => {
return arrays.reduce((acc, curr) => {
const result = [];
acc.forEach(accItem => {
curr.forEach(currItem => {
result.push([...accItem, currItem]);
});
});
return result;
}, [[]]);
};
console.log(cartesianProduct(arr));
[ [ 0, 0, 0 ], [ 0, 0, 1 ], [ 0, 0, 2 ], [ 0, 1, 0 ], [ 0, 1, 1 ], [ 0, 1, 2 ], [ 0, 2, 0 ], [ 0, 2, 1 ], [ 0, 2, 2 ], [ 0, 3, 0 ], [ 0, 3, 1 ], [ 0, 3, 2 ], [ 1, 0, 0 ], [ 1, 0, 1 ], [ 1, 0, 2 ], [ 1, 1, 0 ], [ 1, 1, 1 ], [ 1, 1, 2 ], [ 1, 2, 0 ], [ 1, 2, 1 ], [ 1, 2, 2 ], [ 1, 3, 0 ], [ 1, 3, 1 ], [ 1, 3, 2 ] ]
How It Works
The recursive approach uses a helper function that:
- Iterates through each element in the current array level
- Adds each element to the current combination
- If it's the last array, adds the combination to results
- Otherwise, recursively processes the next array level
The iterative approach builds combinations step by step, starting with an empty array and expanding it with each subsequent array.
Conclusion
Both approaches effectively generate all possible combinations from multiple arrays. The recursive method is more intuitive, while the iterative approach using reduce is more functional in style.
