It helps to visualize the algorithm. Given the list a b c
, these are the combinations we want to generate:
Single character combinations:
a b c
1
a b c
1
a b c
1
Two character combinations:
a b c
1 2
a b c
1 2
a b c
1 2
a b c
2 1
a b c
2 1
a b c
2 1
Three character combinations:
a b c
1 2 3
a b c
1 3 2
etc.
That can be described as "1 to n" combinations, where n is the length of the list.
One approach in code is with the following pair of functions:
let nCombinations = function(list, numItems) {
// Requesting more items than the list isn't possible.
if (list.length < numItems) {
return [];
}
// If requesting 1 item per combination, quickly return a list
// of single item lists.
if (numItems == 1) {
let result = [];
for (let i = 0; i < list.length; i++) {
result.push([list[i]]);
}
return result;
}
// Loop through the list, combining each element with all the
// permutations of the remaining elements.
let result = [];
for (let i = 0; i < list.length; i++) {
let currentElement = list.slice(i, i + 1);
let restList = list.slice(0, i).concat(list.slice(i + 1));
let restCombinations = nCombinations(restList, numItems - 1);
for (let j = 0; j < restCombinations.length; j++) {
result.push(
currentElement.concat(restCombinations[j]));
}
}
return result;
}
let combinations = function(list) {
let result = [];
// Loop through the "1 to n" combinations
for (let i = 1; i <= list.length; i++) {
i_combinations = nCombinations(list, i);
for (let j = 0; j < i_combinations.length; j++) {
result.push(i_combinations[j]);
}
}
return result;
}
Using them with:
const OPTIONS = [
['Cherry', 'Lime', 'Banana'],
['Cherry', 'Lime', 'Banana', 'Orange', 'Apple'],
['Cherry'],
['Cherry', 'Lime'],
['Cherry', 'Lime', 'Banana', 'Orange']
];
for (var i = 0; i < OPTIONS.length; i++) {
console.log('Option ' + (i + 1) + ': ' + OPTIONS[i]);
console.log(combinations(OPTIONS[i]));
}
Produces the following output:
w$ node select-fruits.js
Option 1: Cherry,Lime,Banana
[ [ 'Cherry' ],
[ 'Lime' ],
[ 'Banana' ],
[ 'Cherry', 'Lime' ],
[ 'Cherry', 'Banana' ],
[ 'Lime', 'Cherry' ],
[ 'Lime', 'Banana' ],
[ 'Banana', 'Cherry' ],
[ 'Banana', 'Lime' ],
[ 'Cherry', 'Lime', 'Banana' ],
[ 'Cherry', 'Banana', 'Lime' ],
[ 'Lime', 'Cherry', 'Banana' ],
[ 'Lime', 'Banana', 'Cherry' ],
[ 'Banana', 'Cherry', 'Lime' ],
[ 'Banana', 'Lime', 'Cherry' ] ]
Option 2: Cherry,Lime,Banana,Orange,Apple
[ [ 'Cherry' ],
[ 'Lime' ],
[ 'Banana' ],
[ 'Orange' ],
[ 'Apple' ],
[ 'Cherry', 'Lime' ],
[ 'Cherry', 'Banana' ],
[ 'Cherry', 'Orange' ],
[ 'Cherry', 'Apple' ],
[ 'Lime', 'Cherry' ],
[ 'Lime', 'Banana' ],
[ 'Lime', 'Orange' ],
[ 'Lime', 'Apple' ],
[ 'Banana', 'Cherry' ],
[ 'Banana', 'Lime' ],
[ 'Banana', 'Orange' ],
[ 'Banana', 'Apple' ],
[ 'Orange', 'Cherry' ],
[ 'Orange', 'Lime' ],
[ 'Orange', 'Banana' ],
[ 'Orange', 'Apple' ],
[ 'Apple', 'Cherry' ],
[ 'Apple', 'Lime' ],
[ 'Apple', 'Banana' ],
[ 'Apple', 'Orange' ],
[ 'Cherry', 'Lime', 'Banana' ],
[ 'Cherry', 'Lime', 'Orange' ],
[ 'Cherry', 'Lime', 'Apple' ],
[ 'Cherry', 'Banana', 'Lime' ],
[ 'Cherry', 'Banana', 'Orange' ],
[ 'Cherry', 'Banana', 'Apple' ],
[ 'Cherry', 'Orange', 'Lime' ],
[ 'Cherry', 'Orange', 'Banana' ],
[ 'Cherry', 'Orange', 'Apple' ],
[ 'Cherry', 'Apple', 'Lime' ],
[ 'Cherry', 'Apple', 'Banana' ],
[ 'Cherry', 'Apple', 'Orange' ],
[ 'Lime', 'Cherry', 'Banana' ],
[ 'Lime', 'Cherry', 'Orange' ],
[ 'Lime', 'Cherry', 'Apple' ],
[ 'Lime', 'Banana', 'Cherry' ],
[ 'Lime', 'Banana', 'Orange' ],
[ 'Lime', 'Banana', 'Apple' ],
[ 'Lime', 'Orange', 'Cherry' ],
[ 'Lime', 'Orange', 'Banana' ],
[ 'Lime', 'Orange', 'Apple' ],
[ 'Lime', 'Apple', 'Cherry' ],
[ 'Lime', 'Apple', 'Banana' ],
[ 'Lime', 'Apple', 'Orange' ],
[ 'Banana', 'Cherry', 'Lime' ],
[ 'Banana', 'Cherry', 'Orange' ],
[ 'Banana', 'Cherry', 'Apple' ],
[ 'Banana', 'Lime', 'Cherry' ],
[ 'Banana', 'Lime', 'Orange' ],
[ 'Banana', 'Lime', 'Apple' ],
[ 'Banana', 'Orange', 'Cherry' ],
[ 'Banana', 'Orange', 'Lime' ],
[ 'Banana', 'Orange', 'Apple' ],
[ 'Banana', 'Apple', 'Cherry' ],
[ 'Banana', 'Apple', 'Lime' ],
[ 'Banana', 'Apple', 'Orange' ],
[ 'Orange', 'Cherry', 'Lime' ],
[ 'Orange', 'Cherry', 'Banana' ],
[ 'Orange', 'Cherry', 'Apple' ],
[ 'Orange', 'Lime', 'Cherry' ],
[ 'Orange', 'Lime', 'Banana' ],
[ 'Orange', 'Lime', 'Apple' ],
[ 'Orange', 'Banana', 'Cherry' ],
[ 'Orange', 'Banana', 'Lime' ],
[ 'Orange', 'Banana', 'Apple' ],
[ 'Orange', 'Apple', 'Cherry' ],
[ 'Orange', 'Apple', 'Lime' ],
[ 'Orange', 'Apple', 'Banana' ],
[ 'Apple', 'Cherry', 'Lime' ],
[ 'Apple', 'Cherry', 'Banana' ],
[ 'Apple', 'Cherry', 'Orange' ],
[ 'Apple', 'Lime', 'Cherry' ],
[ 'Apple', 'Lime', 'Banana' ],
[ 'Apple', 'Lime', 'Orange' ],
[ 'Apple', 'Banana', 'Cherry' ],
[ 'Apple', 'Banana', 'Lime' ],
[ 'Apple', 'Banana', 'Orange' ],
[ 'Apple', 'Orange', 'Cherry' ],
[ 'Apple', 'Orange', 'Lime' ],
[ 'Apple', 'Orange', 'Banana' ],
[ 'Cherry', 'Lime', 'Banana', 'Orange' ],
[ 'Cherry', 'Lime', 'Banana', 'Apple' ],
[ 'Cherry', 'Lime', 'Orange', 'Banana' ],
[ 'Cherry', 'Lime', 'Orange', 'Apple' ],
[ 'Cherry', 'Lime', 'Apple', 'Banana' ],
[ 'Cherry', 'Lime', 'Apple', 'Orange' ],
[ 'Cherry', 'Banana', 'Lime', 'Orange' ],
[ 'Cherry', 'Banana', 'Lime', 'Apple' ],
[ 'Cherry', 'Banana', 'Orange', 'Lime' ],
[ 'Cherry', 'Banana', 'Orange', 'Apple' ],
[ 'Cherry', 'Banana', 'Apple', 'Lime' ],
[ 'Cherry', 'Banana', 'Apple', 'Orange' ],
[ 'Cherry', 'Orange', 'Lime', 'Banana' ],
[ 'Cherry', 'Orange', 'Lime', 'Apple' ],
[ 'Cherry', 'Orange', 'Banana', 'Lime' ],
... 225 more items ]
Option 3: Cherry
[ [ 'Cherry' ] ]
Option 4: Cherry,Lime
[ [ 'Cherry' ],
[ 'Lime' ],
[ 'Cherry', 'Lime' ],
[ 'Lime', 'Cherry' ] ]
Option 5: Cherry,Lime,Banana,Orange
[ [ 'Cherry' ],
[ 'Lime' ],
[ 'Banana' ],
[ 'Orange' ],
[ 'Cherry', 'Lime' ],
[ 'Cherry', 'Banana' ],
[ 'Cherry', 'Orange' ],
[ 'Lime', 'Cherry' ],
[ 'Lime', 'Banana' ],
[ 'Lime', 'Orange' ],
[ 'Banana', 'Cherry' ],
[ 'Banana', 'Lime' ],
[ 'Banana', 'Orange' ],
[ 'Orange', 'Cherry' ],
[ 'Orange', 'Lime' ],
[ 'Orange', 'Banana' ],
[ 'Cherry', 'Lime', 'Banana' ],
[ 'Cherry', 'Lime', 'Orange' ],
[ 'Cherry', 'Banana', 'Lime' ],
[ 'Cherry', 'Banana', 'Orange' ],
[ 'Cherry', 'Orange', 'Lime' ],
[ 'Cherry', 'Orange', 'Banana' ],
[ 'Lime', 'Cherry', 'Banana' ],
[ 'Lime', 'Cherry', 'Orange' ],
[ 'Lime', 'Banana', 'Cherry' ],
[ 'Lime', 'Banana', 'Orange' ],
[ 'Lime', 'Orange', 'Cherry' ],
[ 'Lime', 'Orange', 'Banana' ],
[ 'Banana', 'Cherry', 'Lime' ],
[ 'Banana', 'Cherry', 'Orange' ],
[ 'Banana', 'Lime', 'Cherry' ],
[ 'Banana', 'Lime', 'Orange' ],
[ 'Banana', 'Orange', 'Cherry' ],
[ 'Banana', 'Orange', 'Lime' ],
[ 'Orange', 'Cherry', 'Lime' ],
[ 'Orange', 'Cherry', 'Banana' ],
[ 'Orange', 'Lime', 'Cherry' ],
[ 'Orange', 'Lime', 'Banana' ],
[ 'Orange', 'Banana', 'Cherry' ],
[ 'Orange', 'Banana', 'Lime' ],
[ 'Cherry', 'Lime', 'Banana', 'Orange' ],
[ 'Cherry', 'Lime', 'Orange', 'Banana' ],
[ 'Cherry', 'Banana', 'Lime', 'Orange' ],
[ 'Cherry', 'Banana', 'Orange', 'Lime' ],
[ 'Cherry', 'Orange', 'Lime', 'Banana' ],
[ 'Cherry', 'Orange', 'Banana', 'Lime' ],
[ 'Lime', 'Cherry', 'Banana', 'Orange' ],
[ 'Lime', 'Cherry', 'Orange', 'Banana' ],
[ 'Lime', 'Banana', 'Cherry', 'Orange' ],
[ 'Lime', 'Banana', 'Orange', 'Cherry' ],
[ 'Lime', 'Orange', 'Cherry', 'Banana' ],
[ 'Lime', 'Orange', 'Banana', 'Cherry' ],
[ 'Banana', 'Cherry', 'Lime', 'Orange' ],
[ 'Banana', 'Cherry', 'Orange', 'Lime' ],
[ 'Banana', 'Lime', 'Cherry', 'Orange' ],
[ 'Banana', 'Lime', 'Orange', 'Cherry' ],
[ 'Banana', 'Orange', 'Cherry', 'Lime' ],
[ 'Banana', 'Orange', 'Lime', 'Cherry' ],
[ 'Orange', 'Cherry', 'Lime', 'Banana' ],
[ 'Orange', 'Cherry', 'Banana', 'Lime' ],
[ 'Orange', 'Lime', 'Cherry', 'Banana' ],
[ 'Orange', 'Lime', 'Banana', 'Cherry' ],
[ 'Orange', 'Banana', 'Cherry', 'Lime' ],
[ 'Orange', 'Banana', 'Lime', 'Cherry' ] ]