2016-09-22 70 views
1

免責聲明:我知道這個問題的一部分已被要求,並回答了這裏之前,是的,他們幫助我得到了這一點至今。找到從陣列中的所有組合序列JS

比方說,我有一個包含2個元素的數組,我想找到可以由這些要素構成的所有可能的組合。這些集合的順序無關緊要。

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

期望的結果

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

起初我還以爲我一直在尋找但設置了開機我不想null一套,我想對待[a,b][b,a]獨特序列不等於。有關sets,null set和equal sets的更多信息here

到目前爲止,我已經寫了這個功能,將通過我的數組遞歸循環,對於每一個可能的組合創建新的陣列,並將它們推到一個結果數組。

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]] 

} 

這是一個fiddle與我的上述代碼。

目前我只返回3個可能的組合[a], [a,b], [b],如何編輯我的代碼以便我返回[a], [a,b], [b], [b,a]

謝謝!

+0

如果你想使它與'set.length> = 3'一起工作,這將變得有趣。一種方法可能是首先計算powerset,然後刪除'null'並添加每個子集的所有[permutations](http://stackoverflow.com/a/9960925/3828957),長度> 1。 (這意味着你可以計算所有子集的排列+刪除空集,具有1個元素的集合可以跳過)。 – makadev

+0

你不問組合,而是組合的排列。 – Redu

+0

我認爲排列只對數組中的元素重新排序。例如'var arr = [1,2,3]; '排列可以是[1,2,3],[2,1,3],[3,2,1],[3,1,2],[2,3,1],[1,3, 2]'。他們將不包括'[1],[1,2],[2,1],[3,2]'我想我需要找到像@makadev每個子集的排列稱 – user1876246

回答

1

你可以在相反的順序兩個數組:

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(); 

} 
+0

不正是我之後,我想能夠使用此功能與任何規模的陣列。 – user1876246

+0

在我的示例中,我對它進行了硬編碼,但您也可以通過執行類似var myArr = ['a','b']的動態來使用它。var myArr2 = myArr.reverse(); – DinaDee

1

試試這個,適用於所有的數組大小:

的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; 

}