2

Disclaimer: I know part of this question has been asked and answered here before and yes, they have helped me get to this point so far.

Let's say I have an array that contains 2 elements and I want to find ALL possible combinations that could be made up of these elements. The order of the sets does not matter.

var myArr = ['a','b'];

Desired result

var result = [ [a], [a,b], [b], [b,a] ]

At first I thought I was looking for a power set however I do not want a null set and I want to treat [a,b] and [b,a] as unique sequences NOT as equals. More info about sets, null set, and equal sets here.

So far I have written this function that will recursively loop through my array, create new arrays for each possible combinations and push them into a results array.

function getCombinations() {

    var myArr = ['a','b'],
    result = [];

    var recurFn = function(prefix, myArr) {

        for (var i = 0; i < myArr.length; i++) {

            var newArray = prefix !== '' ? [prefix, myArr[i]] : [myArr[i]];
            result.push(newArray);
        recurFn(prefix + myArr[i], myArr.slice(i + 1));
        }
    }

    recurFn('', myArr);
    console.log(result); //[[a], [a,b], [b]]

}

Here is a fiddle with my above code.

Currently I am only returning 3 possible combinations [a], [a,b], [b], how can I edit my code so that I am returning [a], [a,b], [b], [b,a].

Thanks!

user1876246
  • 1,219
  • 5
  • 18
  • 33
  • If you want to make it work with `set.length >= 3`this will get funny. One approach might be to calculate the powerset first, then remove the `null` and add all [permutations](http://stackoverflow.com/a/9960925/3828957) of every subset with `length > 1`. (Which means you calculate the Permutation of all subsets + dropping empty set, sets with 1 element can be skipped tho). – makadev Sep 22 '16 at 13:58
  • you are not asking the combinations but the permutations of the items. – Redu Sep 22 '16 at 14:08
  • I thought permutations were reordering the elements in the array only. For example `var arr = [1,2,3]; ` Permutations would be `[1,2,3], [2,1,3], [3,2,1], [3,1,2], [2,3,1], [1,3,2]`. They would not include `[1], [1,2], [2,1], [3,2]` I think I need to find the permutations of each subset like @makadev says – user1876246 Sep 22 '16 at 14:26
  • Seems it may be simpler. Have [a look at this smooth code](http://codereview.stackexchange.com/a/7025), with sample and all. – makadev Sep 22 '16 at 14:50
  • @makadev any idea how I can use that code to take an array and output an array containing arrays? – user1876246 Sep 22 '16 at 15:02
  • Small adjustments to use array instead of string: https://jsfiddle.net/801zhjws/, just noticed that it creates `[1, 2], [1, 3], [2, 3]` but not the permutations. – makadev Sep 22 '16 at 15:17
  • Updated fiddle which has both combinations and permutations of sets: https://jsfiddle.net/cobvj6wy/ – makadev Sep 22 '16 at 15:30

2 Answers2

1

Can you make two arrays in reverse order:

var myArr = ['a','b']
var myArr2 = ['b','a']

var recurFn = function(prefix, myArr) {

    for (var i = 0; i < myArr.length; i++) {

        var newArray = prefix !== '' ? [prefix, myArr[i]] : [myArr[i]];
        result.push(newArray);
    recurFn(prefix + myArr[i], myArr.slice(i + 1));
    }
    for (var i = 0; i < myArr2.length; i++) {

        var newArray2 = prefix !== '' ? [prefix, myArr2[i]] : [myArr2[i]];
        result.push(newArray2);
    recurFn(prefix + myArr2[i], myArr2.slice(i + 1));
    }
newArray.concat(newArray2);
newArray.unique();

}
DinaDee
  • 247
  • 1
  • 2
  • 11
  • Not exactly what I'm after, I would like to be able to use this function with any array of any size. – user1876246 Sep 22 '16 at 14:37
  • In My example, I hardcoded it, but you can use this dynamically also by doing something like var myArr = ['a','b'] var myArr2 = myArr.reverse(); – DinaDee Sep 22 '16 at 14:44
1

Try this, works for all array sizes:

jsfiddle: https://jsfiddle.net/fcwa3cz5/2/

console.log(allArrCombi(['a','b','c']));

function allArrCombi(arr){
var hash={};
var res=[];
arr.sort();
var len=Math.pow(2, arr.length);
for (var i=1;i<len;i++){
    var lineRes=[];
    for (var innerPos=0;innerPos < arr.length;innerPos++){
        var mask = 1 << innerPos;

        if (mask & i){
            lineRes.push(arr[innerPos]);
        }
    }
    do{
        if (!hash[arr.join("-")]){ // did we have this combinatin already
            res.push(lineRes.slice())
        }
    }while(nextPermutation(lineRes))
}

    return res;
}


function nextPermutation(array) {

var i = array.length - 1;
while (i > 0 && array[i - 1] >= array[i])
    i--;
if (i <= 0)
    return false;


var j = array.length - 1;
while (array[j] <= array[i - 1])
    j--;
var temp = array[i - 1];
array[i - 1] = array[j];
array[j] = temp;


j = array.length - 1;
while (i < j) {
    temp = array[i];
    array[i] = array[j];
    array[j] = temp;
    i++;
    j--;
}
return true;

}

O_Z
  • 1,515
  • 9
  • 11