Foros del Web » Programando para Internet » Javascript »

como realizo todas las combinaciones posibles entre elementos de arrays

Estas en el tema de como realizo todas las combinaciones posibles entre elementos de arrays en el foro de Javascript en Foros del Web. Buenas tardes, intento realizar un algoritmo que datos n arrays, pueda combinar cada elemento de los arrays, de esta manera. Código: var a = ['M', ...
  #1 (permalink)  
Antiguo 26/10/2014, 17:19
Avatar de Copia  
Fecha de Ingreso: noviembre-2009
Mensajes: 309
Antigüedad: 14 años, 5 meses
Puntos: 4
Pregunta como realizo todas las combinaciones posibles entre elementos de arrays

Buenas tardes, intento realizar un algoritmo que datos n arrays, pueda combinar cada elemento de los arrays, de esta manera.
Código:
var a = ['M', 'F'];
var b = ['Pobre', 'Rico', 'Medio'];
var c = ['Lima', 'Chiclayo', 'Trujillo'];
Combinacion a y b:
Código:
(M, Pobre) , (M, Rico ), (M, Medio)
(F, Pobre),   (F, Rico ), (F, Medio)
Si agregaria un tercer elemento a, b y c:
(M, Pobre, Lima) , (M, Rico, Lima ), (M, Medio, Lima)

El orden no importa, pero si que no se repitan las combinaciones, realice dos algoritmos pero con ninguno logro realizar las combinaciones correctamente:

Algoritmo 1:
Código:
var a = ['M', 'F'];
var b = ['Pobre', 'Rico', 'Medio'];
var c = ['Lima', 'Chiclayo', 'Trujillo'];


var ob = [];
var arrays = [a, b, c];

for(var j = 0; j < arrays.length; j++ ){
     ob[j] = [];
     for(var i=0; i < 18; i = i + arrays[j].length){       
        for(k=0; k < arrays[j].length; k++){
          ob[j].push(arrays[j][k]);          
          console.log(arrays[j][k]);
        }
     }
  console.log('................');
  }
Y en este segundo algoritmo intento usar una funcion recursiva sin exito:

Código:
function mesclar(){
  if(arguments.length ==  2) {
    //console.log(arguments);
    return arguments[1][0][arguments[0].posicion];
  }
  else{
    var arg = Array.prototype.splice.call(arguments, 2);
    //console.log(arg);
    var cad = '';
    for(var i=0; i<arguments[1].length; i++){
      arguments[0].posicion = i;
      cad = cad + ' - ' + arguments[1][i] + ' - '+ mesclar(arguments[0], arg) ;
    }
    console.log(cad, ' aaa ');
  }  
}

mesclar({posicion:0}, b,c);
He estado dando vueltas a esto durante el día sin exito, que podria hacer?
__________________
Dejando una huella de mi existencia por la red en http://tiricaya.com
  #2 (permalink)  
Antiguo 26/10/2014, 18:59
Avatar de Alexis88
Philosopher
 
Fecha de Ingreso: noviembre-2011
Ubicación: Tacna, Perú
Mensajes: 5.552
Antigüedad: 12 años, 5 meses
Puntos: 977
Respuesta: como realizo todas las combinaciones posibles entre elementos de arrays

Podrías hacerlo así:

Código Javascript:
Ver original
  1. var a = ['M', 'F'],
  2.     b = ['Pobre', 'Rico', 'Medio'],
  3.     c = ['Lima', 'Chiclayo', 'Trujillo'];
  4.  
  5. (function(x, y, z){
  6.     var final = [];
  7.     for (var i = 0, l = x.length; i < l; i++){
  8.         for (var j = 0, k = 0, m = y.length, n = z.length; j < m; j++){
  9.             final.push([a[i], b[j], c[k]]);
  10.             if (j == m - 1 && k < n - 1){
  11.                k++;
  12.                j = -1;
  13.             }
  14.         }
  15.     }
  16.     console.log(final);
  17. })(a, b, c);

Lo cual dará por resultado lo siguiente:

Código Console:
Ver original
  1. Array(
  2.     Array(M, Pobre, Lima),
  3.     Array(M, Rico, Lima),
  4.     Array(M, Medio, Lima),
  5.     Array(M, Pobre, Chiclayo),
  6.     Array(M, Rico, Chiclayo),
  7.     Array(M, Medio, Chiclayo),
  8.     Array(M, Pobre, Trujillo),
  9.     Array(M, Rico, Trujillo),
  10.     Array(M, Medio, Trujillo),
  11.     Array(F, Pobre, Lima),
  12.     Array(F, Rico, Lima),
  13.     Array(F, Medio, Lima),
  14.     Array(F, Pobre, Chiclayo),
  15.     Array(F, Rico, Chiclayo),
  16.     Array(F, Medio, Chiclayo),
  17.     Array(F, Pobre, Trujillo),
  18.     Array(F, Rico, Trujillo),
  19.     Array(F, Medio, Trujillo)
  20. )

Lo que hago es simple. Recorro al primer array y, en cada iteración, recorro al segundo, en donde, además, declaro un contador para ir tomando los valores del tercer array. En cada iteración de este segundo bucle, inserto un nuevo array dentro del array final con los valores equivalentes a los contadores en cada iteración y solo cuando el valor del contador del segundo array sea igual a la última posición de este y el contador del tercero sea menor que la última posición del suyo, incremento el valor del tercer contador y asigno -1 al segundo contador pues, al final de esa iteración, su valor se incrementará en uno, con lo cual, terminará siendo igual a cero.

Saludos
__________________
«Juro por mi vida y mi amor por ella, que jamás viviré para el provecho de otro hombre, ni le pediré a otro hombre que viva para el mío».

Ayn Rand
  #3 (permalink)  
Antiguo 26/10/2014, 19:27
Avatar de Copia  
Fecha de Ingreso: noviembre-2009
Mensajes: 309
Antigüedad: 14 años, 5 meses
Puntos: 4
Respuesta: como realizo todas las combinaciones posibles entre elementos de arrays

Gracias Alexis88, la solucion que planteas es buena, yo no lo habia pensado de esa manera.
El grueso de este problema, es no saber cuantos arrays tengo que combinar, por eso el segundo algoritmo que planteo es recursivo y apoyandome en arguments, para saber la cantidad de arrays que me envien.
__________________
Dejando una huella de mi existencia por la red en http://tiricaya.com
  #4 (permalink)  
Antiguo 26/10/2014, 22:43
Avatar de Alexis88
Philosopher
 
Fecha de Ingreso: noviembre-2011
Ubicación: Tacna, Perú
Mensajes: 5.552
Antigüedad: 12 años, 5 meses
Puntos: 977
Respuesta: como realizo todas las combinaciones posibles entre elementos de arrays

Antes de pensar en una solución, dime, ¿cuál es el fin de hacer esto? Es que, siendo sincero, no le encuentro mucho sentido al relacionar datos de esa manera. Si los extraes de una BD (suponiendo que fuera así), bastaría con relacionar a las tablas que los contienen y mediante consultas SQL, tomarlos. Quizá si nos explicas cuál es el fin de esto, podremos pensar en una solución más eficiente y eficaz.

Saludos
__________________
«Juro por mi vida y mi amor por ella, que jamás viviré para el provecho de otro hombre, ni le pediré a otro hombre que viva para el mío».

Ayn Rand
  #5 (permalink)  
Antiguo 26/10/2014, 22:54
Avatar de Copia  
Fecha de Ingreso: noviembre-2009
Mensajes: 309
Antigüedad: 14 años, 5 meses
Puntos: 4
Respuesta: como realizo todas las combinaciones posibles entre elementos de arrays

Claro, tengo este caso: Yo realizo preguntas tipo encuesta, por ejemplo
Cual es su sexo? y opcion es M, F.
Donde Vive: Lima, Trujillo, Chiclayo.
Nivel Socioeconomico: A, B, C, D

Encontonces lo que busco es alertar a los usuarios, por ejemplo cuando 10 personas de trujillo marquen que son de nivel socioeconomico C.

Como no se cuantas relaciones necesiten hacer los usuarios, quiero encontrar una solucion generica con los algoritmos. Con esto yo construire una tabla y Columna A, Columna B, Alerta. donde alerta me dice la relación de estas columnas.
__________________
Dejando una huella de mi existencia por la red en http://tiricaya.com
  #6 (permalink)  
Antiguo 27/10/2014, 01:44
Avatar de Alexis88
Philosopher
 
Fecha de Ingreso: noviembre-2011
Ubicación: Tacna, Perú
Mensajes: 5.552
Antigüedad: 12 años, 5 meses
Puntos: 977
Respuesta: como realizo todas las combinaciones posibles entre elementos de arrays

No creo que sea necesario hacerlo de la manera en que la planteas. Podrías generar un bucle que itere N veces y en cada iteración, realizas cada una de las preguntas, las mismas que podrías guardar en objetos y cada uno de estos en un array general. Teniendo todos estos datos organizados de tal manera, cualquier búsqueda o muestra de datos, será mucho más sencilla.

Un ejemplo:
Código Javascript:
Ver original
  1. function encuesta(n, preg){
  2.     for (var i = 0, result = [], aux = {}; i < n; i++){
  3.         for (var j in preg) aux[j] = prompt(preg[j]);
  4.         result.push(aux);
  5.         aux = {};
  6.     }
  7.     return console.log(result);
  8. }
  9. encuesta(3, {
  10.     sexo: "Sexo (M|F):",
  11.     lugar: "Lugar:",
  12.     nivel: "Nivel (A|B|C|D):"
  13. });

Si, por ejemplo, las respuestas fueran: (M, Tacna, A), (F, Lima, C), (M, Trujillo, D), el resultado final sería así (las propiedades de los objetos se ordenan alfabéticamente de forma automática):

Código Console:
Ver original
  1. Array(
  2.     {
  3.         lugar: Tacna,
  4.         nivel: A,
  5.         sexo: M
  6.     },
  7.     {
  8.         lugar: Lima,
  9.         nivel: C,
  10.         sexo: F
  11.     },
  12.     {
  13.         lugar: Trujillo,
  14.         nivel: D,
  15.         sexo: M
  16.     },
  17. )

El proceso es simple. Envío a la función la cantidad de encuestados y las preguntas dentro de un objeto literal. En la función, creo un bucle que iterará N veces (las que haya indicado) y, en cada iteración, recorreré el objeto con las preguntas y las iré realizando una por una. Cada resultado lo guardo en otro objeto literal y finalizada la ronda de preguntas al encuestado, guardo dicho conjunto de datos en el array principal y limpio el objeto auxiliar que es en el que guardo temporalmente las respuestas de cada encuestado. Y si te fijas, tanto la cantidad de encuestados como las preguntas, pueden variar.

Saludos
__________________
«Juro por mi vida y mi amor por ella, que jamás viviré para el provecho de otro hombre, ni le pediré a otro hombre que viva para el mío».

Ayn Rand
  #7 (permalink)  
Antiguo 27/10/2014, 17:56
Avatar de HackmanC  
Fecha de Ingreso: enero-2008
Ubicación: Guatemala
Mensajes: 1.817
Antigüedad: 16 años, 3 meses
Puntos: 260
Sonrisa Respuesta: como realizo todas las combinaciones posibles entre elementos de arrays

Hola,

Cita:
Iniciado por Alexis88 Ver Mensaje
Lo que hago es simple. Recorro al primer array y, en cada iteración, recorro al segundo, en donde, además, declaro un contador para ir tomando los valores del tercer array. En cada iteración de este segundo bucle, inserto un nuevo array dentro del array final con los valores equivalentes a los contadores en cada iteración y solo cuando el valor del contador del segundo array sea igual a la última posición de este y el contador del tercero sea menor que la última posición del suyo, incremento el valor del tercer contador y asigno -1 al segundo contador pues, al final de esa iteración, su valor se incrementará en uno, con lo cual, terminará siendo igual a cero.
Si lo pones así se mira realmente difícil, técnicamente creo que estas haciendo a' x b' x c', multiplicación de vectores para obtener su producto cartesiano, y creo que posiblemente la solución mas simple sea algo así:

Código Javascript:
Ver original
  1. var t = [];
  2. for (i = 0; i < a.length; i++) {
  3.   for (j = 0; j < b.length; j++) {
  4.     for (k = 0; k < c.length; k++) {
  5.       t.push([a[i], b[j], c[k]]);
  6.     }
  7.   }
  8. }
  9. console.log(t);
http://www.forosdelweb.com/f18/desaf...3/#post4433005

Cita:
Iniciado por Alexis88 Ver Mensaje
... Si los extraes de una BD (suponiendo que fuera así), bastaría con relacionar a las tablas que los contienen y mediante consultas SQL, ...
Cita:
Iniciado por Copia Ver Mensaje
... Encontonces lo que busco es alertar a los usuarios, por ejemplo cuando 10 personas de trujillo marquen que son de nivel socioeconomico C.

Como no se cuantas relaciones necesiten hacer los usuarios, quiero encontrar una solucion generica con los algoritmos. Con esto yo construire una tabla y Columna A, Columna B, Alerta. donde alerta me dice la relación de estas columnas.
Yo en lo personal no he comprendido bien la utilidad que le vas a dar, como bien indica Alexis88 definitivamente la mejor opción sería en la base de datos. La parte mas confusa es donde dice: 10 personas, supongo que los resultados vienen de la base de datos, y extraer esa información usando el lenguaje SQL es mucho mas simple.

Pero aún así, si es te de utilidad posiblemente puedas hacer parecido a esto, te extrae el producto cartesiano de N vectores, multiplicando cada uno de los vectores con el resultado previo, recursivamente:

Código Javascript:
Ver original
  1. function imul(a, b) {
  2.   var r = [];
  3.   for (var i = 0; i < a.length; i++) {
  4.     for (var j = 0; j < b.length; j++) {
  5.       r.push(b[j].concat(a[i]));
  6.     }
  7.   }
  8.   return r;
  9. }
  10.  
  11. function tree(previous, argument) {
  12.   if (argument.length == 0) {
  13.     return previous.map(function (x) {
  14.       return [x];
  15.     });
  16.   }
  17.   return imul(previous, tree(argument[0], argument.slice(1)));
  18. }
  19.  
  20. function build() {
  21.   var argument = Array.prototype.slice.apply(arguments, [0]);
  22.   return tree(argument[0], argument.slice(1));
  23. }
  24.  
  25. console.log(build(a, b, c));

En los dos casos a, b y c, son los vectores del post orginal,

Saludos,
  #8 (permalink)  
Antiguo 27/10/2014, 20:12
Avatar de Alexis88
Philosopher
 
Fecha de Ingreso: noviembre-2011
Ubicación: Tacna, Perú
Mensajes: 5.552
Antigüedad: 12 años, 5 meses
Puntos: 977
Respuesta: como realizo todas las combinaciones posibles entre elementos de arrays

Cita:
Iniciado por HackmanC Ver Mensaje
Técnicamente creo que estas haciendo a' x b' x c', multiplicación de vectores para obtener su producto cartesiano, y creo que posiblemente la solución mas simple sea algo así:

Código Javascript:
Ver original
  1. var t = [];
  2. for (i = 0; i < a.length; i++) {
  3.   for (j = 0; j < b.length; j++) {
  4.     for (k = 0; k < c.length; k++) {
  5.       t.push([a[i], b[j], c[k]]);
  6.     }
  7.   }
  8. }
  9. console.log(t);
En realidad, lo hice así porque, como el mismo Copia me aclaró en una respuesta anterior, la cantidad de preguntas puede ser variable, entonces, trabajando con un objeto que almacene las N preguntas, bastaría con recorrerlo e ir formulando cada una de las N preguntas a la M personas encuestadas.

Ahora que, como dije, puede ser que la información provenga de una BD, entonces, el tratamiento de los datos sería distinto y mucho más eficiente, pero eso es algo que solo Copia sabe y puede aclararnos.

Saludos

Edito: Me acabo de dar cuenta de que replicaste a mi primera respuesta. Lo hice así para intentar formar la figura que Copia expuso: (M, Pobre, Lima), (M, Rico, Lima ), (M, Medio, Lima).
__________________
«Juro por mi vida y mi amor por ella, que jamás viviré para el provecho de otro hombre, ni le pediré a otro hombre que viva para el mío».

Ayn Rand
  #9 (permalink)  
Antiguo 27/10/2014, 21:21
Avatar de HackmanC  
Fecha de Ingreso: enero-2008
Ubicación: Guatemala
Mensajes: 1.817
Antigüedad: 16 años, 3 meses
Puntos: 260
Sonrisa Respuesta: como realizo todas las combinaciones posibles entre elementos de arrays

Hola,

Cita:
Iniciado por Alexis88 Ver Mensaje
... trabajando con un objeto que almacene las N preguntas, bastaría con recorrerlo e ir formulando cada una de las N preguntas a la M personas encuestadas. ...
Esa es la parte que no comprendo en nada. ¿Supuestamente va a ir haciendo las preguntas a cada encuestado en el mismo ordenador, sin guardarlas en la base de datos?. Pero como bien dijiste eso es algo que solamente Copia puede aclararnos.

Cita:
Iniciado por Alexis88 Ver Mensaje
... Edito: Me acabo de dar cuenta de que replicaste a mi primera respuesta. Lo hice así para intentar formar la figura que Copia expuso: (M, Pobre, Lima), (M, Rico, Lima ), (M, Medio, Lima).
Ciertamente, me refería a la primera respuesta que pusiste. No es por llevarte la contraria pero es una multiplicación y en el caso de las multiplicaciones el orden de los factores no altera el producto. Pero suponiendo que quieras alterar el 'orden' del producto, solamente tienes que cambiar el orden de los elementos al concatenarlos (en esta caso el push) o el 'orden' de la iteración.

Por ejemplo:

Código:
var t = [];
for (i = 0; i < a.length; i++) {
  for (k = 0; k < c.length; k++) {
    for (j = 0; j < b.length; j++) {
      t.push([a[i], b[j], c[k]]);
    }
  }
}
console.log(t);
Al cambiar el orden de la iteración j con la k, obtienes el producto ordenado de diferente forma. Pero creo que no es importante realmente, ya Copia mencionó que esa forma no le era útil, solamente quería mostrar una forma diferente de realizar el mismo objetivo.

Saludos,
  #10 (permalink)  
Antiguo 27/10/2014, 22:36
Avatar de Alexis88
Philosopher
 
Fecha de Ingreso: noviembre-2011
Ubicación: Tacna, Perú
Mensajes: 5.552
Antigüedad: 12 años, 5 meses
Puntos: 977
Respuesta: como realizo todas las combinaciones posibles entre elementos de arrays

Cita:
Iniciado por HackmanC Ver Mensaje
¿Supuestamente va a ir haciendo las preguntas a cada encuestado en el mismo ordenador, sin guardarlas en la base de datos?
Claro, ese sería un ejemplo sin el uso de una BD ya que nuestro amigo Copia aún no se decide en decirnos si está utilizando una o no. No lo aclaré porque está implícito.

Cita:
Iniciado por HackmanC Ver Mensaje
En el caso de las multiplicaciones el orden de los factores no altera el producto.
Y te doy la razón, pero por seguir el patrón que Copia expuso, es decir, que primero se incremente el primer contador, luego el tercero y finalmente el segundo, es que decidí hacerlo de esa manera. Invirtiendo el orden de los dos últimos bucles también funciona, solo que quise evitar utilizar un tercer bucle y aunque el algoritmo es sencillo, escribí todo ese párrafo con la explicación debida, para que no le queden dudas.

Saludos
__________________
«Juro por mi vida y mi amor por ella, que jamás viviré para el provecho de otro hombre, ni le pediré a otro hombre que viva para el mío».

Ayn Rand

Última edición por Alexis88; 28/10/2014 a las 12:14 Razón: Fe de erratas

Etiquetas: arrays, combinaciones
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 17:14.