Kodeclik Blog
How to find all combinations of array values in Javascript
Let us suppose I have a list (or array) of grocery items such as ["apples", "bananas", "chips", "dates", "eggs"] and wish to create all pairwise combinations of items (but without generating duplicates). A simple Javascript program for this purpose would be:
const items = ["apples", "bananas", "chips", "dates", "eggs"];
const pairs = [];
for (let i = 0; i < items.length; i++) {
for (let j = i + 1; j < items.length; j++) {
pairs.push([items[i], items[j]]);
}
}
console.log(pairs);
This code uses two nested loops to iterate over the array and generate all possible pairs of items. The outer loop iterates over each item in the array, and the inner loop iterates over the remaining items in the array to generate all pairs that include the current item. The pairs are stored in an array called pairs, which is logged to the console at the end of the code.
The output of this code for the given items would be something like:
[Array(2), Array(2), …
The reason you are getting [Array(2), Array(2), ....] when running the Javascript code is because the console is displaying the arrays as objects, which is the default behavior of console.log() for arrays. To display the contents of the arrays, you can use the console.table() method instead of console.log().
const items = ["apples", "bananas", "chips", "dates", "eggs"];
const pairs = [];
for (let i = 0; i < items.length; i++) {
for (let j = i + 1; j < items.length; j++) {
pairs.push([items[i], items[j]]);
}
}
console.table(pairs);
This will produce:
Note that our code generates all possible pairs of items without any duplicates, meaning that each pair is unique and does not appear in reverse order.
Alternatively, you can simply update the code to say:
const items = ["apples", "bananas", "chips", "dates", "eggs"];
const pairs = [];
for (let i = 0; i < items.length; i++) {
for (let j = i + 1; j < items.length; j++) {
pairs.push([items[i], items[j]]);
}
}
pairs.forEach((x) => {
console.log(x);
});
Here we are doing console.log() on each element of “pairs”. The output will be:
["apples", "bananas"]
["apples", "chips"]
["apples", "dates"]
["apples", "eggs"]
["bananas", "chips"]
["bananas", "dates"]
["bananas", "eggs"]
["chips", "dates"]
["chips", "eggs"]
["dates", "eggs"]
Finding triples of values in Javascript
To get triples of values in Javascript, we extend the above code:
const items = ["apples", "bananas", "chips", "dates", "eggs"];
const triples = [];
for (let i = 0; i < items.length; i++) {
for (let j = i + 1; j < items.length; j++) {
for (let k = j + 1; k < items.length; k++) {
triples.push([items[i], items[j], items[k]]);
}
}
}
triples.forEach((x) => {
console.log(x);
});
This code uses three nested loops to iterate over the array and generate all possible triples of items. The outer loop iterates over each item in the array, the second loop iterates over the remaining items in the array to generate all pairs that include the current item, and the innermost loop iterates over the further remaining items in the array to generate all triples that include the current pair. The triples are stored in an array called triples which looks like:
[
["apples", "bananas", "chips"],
["apples", "bananas", "dates"],
["apples", "bananas", "eggs"],
["apples", "chips", "dates"],
["apples", "chips", "eggs"],
["apples", "dates", "eggs"],
["bananas", "chips", "dates"],
["bananas", "chips", "eggs"],
["bananas", "dates", "eggs"]
]
And thus the console.log() statement will print each element of this array (which is itself an array) on a separate line.
Finding all combinations of values in Javascript
The above gets cumbersome if we want to generate combinations of all sizes, not just a fixed size. To generate combinations of all sizes from the given array, we can use something like the following:
const items = ["apples", "bananas", "chips", "dates", "eggs"];
const combinations = [];
for (let i = 1; i <= items.length; i++) {
for (let j = 0; j <= items.length - i; j++) {
combinations.push(items.slice(j, j + i));
}
}
combinations.forEach((x) => {
console.log(x);
});
This code generates all possible combinations of sizes 1 to n from the given array, where n is the length of the array. The combinations are stored in an array called combinations, which is logged to the console at the end of the code.
The output of this code for the given items would be elements of this array:
[
["apples"],
["bananas"],
["chips"],
["dates"],
["eggs"],
["apples", "bananas"],
["bananas", "chips"],
["chips", "dates"],
["dates", "eggs"],
["apples", "chips"],
["bananas", "dates"],
["chips", "eggs"],
["apples", "dates"],
["bananas", "eggs"],
["apples", "eggs"],
["apples", "bananas", "chips"],
["bananas", "chips", "dates"],
["chips", "dates", "eggs"],
["apples", "chips", "dates"],
["bananas", "dates", "eggs"],
["chips", "dates", "eggs"],
["apples", "bananas", "dates"],
["bananas", "chips", "eggs"],
["apples", "chips", "eggs"],
["apples", "dates", "eggs"],
["bananas", "dates", "eggs"],
["apples", "bananas", "eggs"],
["apples", "bananas", "chips", "dates"],
["bananas", "chips", "dates", "eggs"],
["apples", "chips", "dates", "eggs"],
["apples", "bananas", "dates", "eggs"],
["apples", "bananas", "chips", "eggs"],
["apples", "chips", "dates", "eggs"],
["bananas", "chips", "dates", "eggs"],
["apples", "bananas", "chips", "dates", "eggs"]
]
As you can see, the code generates all possible combinations of sizes 1 to 5 from the given array, where each combination is unique and does not contain any duplicate items or the same items in different orders.
Finding all combinations of values in Javascript by recursion
In this approach, we explore a recursive strategy. The below code generates all possible combinations of the items in the items array by calling the generateCombinations function for each possible combination size, from 1 to the length of the items array. Note that the generateCombinations function uses recursion to generate all possible combinations of the given size. It does this by iterating through the arr array, starting at the start index, and adding each element to the temp array. If the temp array has reached the desired size, it adds a copy of the temp array to the combinations array. If the temp array has not reached the desired size, it calls itself recursively with the next index as the start index and the updated temp array. After all combinations have been generated, the combinations array is printed to the console using a forEach loop as usual.
const items = ["apples", "bananas", "chips", "dates", "eggs"];
const combinations = [];
function generateCombinations(arr, size, start, temp) {
if (temp.length === size) {
combinations.push([...temp]);
return;
}
for (let i = start; i < arr.length; i++) {
temp.push(arr[i]);
generateCombinations(arr, size, i + 1, temp);
temp.pop();
}
}
for (let i = 1; i <= items.length; i++) {
generateCombinations(items, i, 0, []);
}
combinations.forEach((x) => {
console.log(x);
});
The output is as before:
["apples"]
["bananas"]
["chips"]
["dates"]
["eggs"]
["apples", "bananas"]
["apples", "chips"]
["apples", "dates"]
["apples", "eggs"]
["bananas", "chips"]
["bananas", "dates"]
["bananas", "eggs"]
["chips", "dates"]
["chips", "eggs"]
["dates", "eggs"]
["apples", "bananas", "chips"]
["apples", "bananas", "dates"]
["apples", "bananas", "eggs"]
["apples", "chips", "dates"]
["apples", "chips", "eggs"]
["apples", "dates", "eggs"]
["bananas", "chips", "dates"]
["bananas", "chips", "eggs"]
["bananas", "dates", "eggs"]
["chips", "dates", "eggs"]
["apples", "bananas", "chips", "dates"]
["apples", "bananas", "chips", "eggs"]
["apples", "bananas", "dates", "eggs"]
["apples", "chips", "dates", "eggs"]
["bananas", "chips", "dates", "eggs"]
["apples", "bananas", "chips", "dates", "eggs"]
If you liked this blogpost, checkout our blogpost on list/array comprehensions in Javascript.
Want to learn Javascript with us? Sign up for 1:1 or small group classes.