Encontrar todas las combinaciones (producto cartesiano) de valores de matriz de JavaScript

Resuelto Yahel asked hace 13 años • 16 respuestas

¿Cómo puedo producir todas las combinaciones de valores en N números de matrices JavaScript de longitudes variables?

Digamos que tengo N número de matrices de JavaScript, por ejemplo

var first = ['a', 'b', 'c', 'd'];
var second = ['e'];
var third =  ['f', 'g', 'h', 'i', 'j'];

(Tres matrices en este ejemplo, pero es N número de matrices para el problema).

Y quiero generar todas las combinaciones de sus valores, para producir

aef
aeg
aeh
aei
aej
bef
beg
....
dej

EDITAR: Aquí está la versión que tengo funcionando, usando la respuesta aceptada de ffriend como base.

var allArrays = [['a', 'b'], ['c', 'z'], ['d', 'e', 'f']];

 function allPossibleCases(arr) {
  if (arr.length === 0) {
    return [];
  } 
  else if (arr.length ===1){
    return arr[0];
  }
  else {
    var result = [];
    var allCasesOfRest = allPossibleCases(arr.slice(1));  // recur with the rest of array
    for (var c in allCasesOfRest) {
      for (var i = 0; i < arr[0].length; i++) {
        result.push(arr[0][i] + allCasesOfRest[c]);
      }
    }
    return result;
  }

}
var results = allPossibleCases(allArrays);
 //outputs ["acd", "bcd", "azd", "bzd", "ace", "bce", "aze", "bze", "acf", "bcf", "azf", "bzf"]
Yahel avatar Dec 02 '10 09:12 Yahel
Aceptado

Esto no son permutaciones, consulte las definiciones de permutaciones de Wikipedia.

Pero puedes lograr esto con recursividad :

var allArrays = [
  ['a', 'b'],
  ['c'],
  ['d', 'e', 'f']
]

function allPossibleCases(arr) {
  if (arr.length == 1) {
    return arr[0];
  } else {
    var result = [];
    var allCasesOfRest = allPossibleCases(arr.slice(1)); // recur with the rest of array
    for (var i = 0; i < allCasesOfRest.length; i++) {
      for (var j = 0; j < arr[0].length; j++) {
        result.push(arr[0][j] + allCasesOfRest[i]);
      }
    }
    return result;
  }

}

console.log(allPossibleCases(allArrays))
Expandir fragmento

También puedes hacerlo con bucles, pero será un poco complicado y requerirá implementar tu propio análogo de pila.

ffriend avatar Dec 02 '2010 02:12 ffriend

Sugiero una función generadora recursiva simple de la siguiente manera:

// Generate cartesian product of given iterables:
function* cartesian(head, ...tail) {
  let remainder = tail.length ? cartesian(...tail) : [[]];
  for (let r of remainder) for (let h of head) yield [h, ...r];
}

// Example:
const first  = ['a', 'b', 'c', 'd'];
const second = ['e'];
const third  = ['f', 'g', 'h', 'i', 'j'];

console.log(...cartesian(first, second, third));
Expandir fragmento

le_m avatar Jun 02 '2017 23:06 le_m