Question:
I am making an application in JavaScript (with jQuery), in which the main function is to create unique combinations and grouped in a certain number. But the way I do them doesn't seem to be the best way.
Example:
var cadena = [1, 2, 3, 4, 5, 6, 7, 8]; //Caracteres que va a combinar var arrayCombinaciones = []; //Almacena las combinaciones var grupo = 3; //le indico la cantidad de cuantos caracteres quiero que sean las combinaciones. var posicion = 0; switch (grupo) { case 2: for (var i = 0; i < cadena.length; i++) { for (var j = 0; j < cadena.length; j++) { if (cadena[i] != cadena[j]) { arrayCombinaciones[posicion++] = [cadena[i], cadena[j]]; } } } break; case 3: for (var i = 0; i < cadena.length; i++) { for (var j = 0; j < cadena.length; j++) { for (var k = 0; k < cadena.length; k++) { if (cadena[i] != cadena[j] && cadena[i] != cadena[k] && cadena[j] != cadena[k]) { arrayCombinaciones[posicion++] = [cadena[i], cadena[j], cadena[k]]; } } } } break; } console.log(JSON.stringify(arrayCombinaciones));
And in case the group is of two, I need to do two for
and with an if
to validate that the characters are not equal and store the combinations in the "arrayCombinaciones". In this case the result of grouping them by 2 would be:
[["1","2"],["1","3"],["1","4"],["1","5"],["1","6"] ,["1","7"],["1","8"],["2","1"],["2","3"],["2","4"] ,["2","5"],["2","6"],["2","7"],["2","8"],["3","1"] ,["3","2"],["3","4"],["3","5"],["3","6"],["3","7"] ,["3","8"],["4","1"],["4","2"],["4","3"],["4","5"] ,["4","6"],["4","7"],["4","8"],["5","1"],["5","2"] ,["5","3"],["5","4"],["5","6"],["5","7"],["5","8"] ,["6","1"],["6","2"],["6","3"],["6","4"],["6","5"] ,["6","7"],["6","8"],["7","1"],["7","2"],["7","3"] ,["7","4"],["7","5"],["7","6"],["7","8"],["8","1"] ,["8","2"],["8","3"],["8","4"],["8","5"],["8","6"] ,["8","7"]]
What if, for example, I want groups of 10? I must do 10 nested for, but it doesn't seem to me to be the best way, I don't know if there is another way to avoid doing so many for
according to the group number indicated. In short, be dynamic.
Answer:
One way to implement it recursively:
function comb(alfabeto, n, resultados, resultado) { if(!resultado) { resultado = []; } for(var i=0; i<alfabeto.length; ++i) { var newResultado = resultado.slice(); var newAlfabeto = alfabeto.slice(); newResultado.push(alfabeto[i]); newAlfabeto.splice(i, 1); if(n>1) { comb(newAlfabeto, n-1, resultados, newResultado); } else { resultados.push(newResultado); } } } var cadena = [1,2,3,4,5,6,7,8];//Caracteres que va a combinar var arrayCombinaciones = [];//Almacena las combinaciones var grupo = 3;//le indico la cantidad de cuantos caracteres quiero que sean las combinaciones. comb(cadena, grupo, arrayCombinaciones); console.log(JSON.stringify(arrayCombinaciones));
Basically, the function iterates through the entire alphabet and creates as many arrays as there are characters in the alphabet. When calling itself again, it does so with a new alphabet with the used character removed and an incomplete result array.
When I already use the number of characters n
completes the final array of results.