2012-02-07 13 views
5

Tengo un problema bastante único que tengo problemas para resolver. Tengo una mesa de 2 x 3, dispuesta como se muestra a continuación.Combinación de tablas complejas javascript & jquery algorithm

        _ 1 __ _ _ 2 __
1- | _ __ _ | __ _ _ |
2- | _ __ _ | __ _ _ |
3- | _ __ _ | __ _ _ |

Los datos se llenan en las celdas de la tabla. A veces, los datos en una columna o fila pueden ser los mismos. Por ejemplo, si (1,1) y (1,2) tienen los mismos datos. En algunos casos (1,1), (1,2) y (1,3) todos pueden tener los mismos datos. Si los valores en las celdas son iguales y adyacentes, deben fusionarse. Por ejemplo, si (1,1) y (1,2) ambos tienen un valor de "100", las dos celdas se fusionan. He hecho esto de forma manual mediante el uso de jQuery como:

(1,2).hide(); 
(1,1).attr("rowspan", "2"); 

escondo el (1,2) celda en lugar de borrar, ya que las mesas se pueden reajustar a la 2x3 original y luego vuelve a llenar si es necesario. Manualmente, esto funciona muy bien, pero necesito un método dinámico. A continuación se muestra el objetivo general de lo que se necesita lograr.

  • Si dos celdas adyacentes verticalmente o tres celdas adyacentes verticalmente en sus respectivas columnas tienen valores iguales, entonces esas celdas se fusionan.
  • Las celdas de fila, como (1,1) y (2,1) pueden tener datos duplicados y nunca se combinan.
  • Como referencia, los grupos de celdas que se pueden fusionar son {(1,1), (1,2)}, {(1,1), (1,2), (1,3)} , {(1,2), (1,3)}, {(2,1), (2,2)}, {(2,1), (2,2), (2,3)}, { (2,2), (2,3)}
  • Múltiples fusiones pueden suceder a la vez. Por ejemplo: {(1,1), (1,2)} tienen los mismos datos, y {(2,1), (2,2), (2,3)} tienen los mismos datos. Ambos grupos se fusionaron individualmente.

Mi pregunta principal es, ¿cómo voy a escribir un algoritmo para hacer esto, sin escribir todas las situaciones posibles. ¿Puede alguien mostrarme un ejemplo de algo que funcionaría? Me doy cuenta de que esto es complejo, así que siéntase libre de hacer preguntas para aclararlas. Muchas gracias en avanzado. ¡Esto es una gran ayuda!

+0

¿La mesa siempre es 2x3? –

+0

Suena como un trabajo para ... Asignación de Karnaugh. Consulte http://en.wikipedia.org/wiki/Karnaugh_map –

+0

La tabla siempre es originalmente 2 x 3. La combinación de las celdas puede hacer que la tabla se convierta en 2 x 2 o 2 x 1. – dremme

Respuesta

3

Como esta? http://jsfiddle.net/4zGvg/ Funciona con filas/columnas arbitrarias.

La idea: tenemos values matriz y span matriz. Los valores de span son

0 = ocultan esta célula

1 = normal de las células

x> 1 = célula con rowspan x

Iterar por columnas en orden directo y por filas en orden inverso . Si el valor de alguna célula es igual al valor por debajo de ella, aumentar de span esta célula y eliminar el span de la celda de abajo:

for (var col = 0; col < cols; col++) { 
    for (var row = rows - 2; row >= 0; row--) { 
     if (values[row][col] == values[row + 1][col]) { 
      span[row][col] = span[row + 1][col] + 1; 
      span[row + 1][col] = 0; 
     } 
    } 
} 

Una vez hecho esto, puede utilizar span para generar la tabla completa o para mostrar/ocultar celdas y establecer sus atributos rowspan.

+0

Muy bueno. La mejor respuesta que he encontrado. Trataré de implementar esta solución. Gracias. – dremme

2

Dado que siempre es de 2x3, podría simplemente aplicar una fuerza bruta.

http://jsfiddle.net/Csxbf/

var $cells = $("td"); 

if ($cells.eq(0).text() == $cells.eq(2).text()) { 

    if ($cells.eq(2).text() == $cells.eq(4).text()) { 
     $cells.eq(2).hide(); 
     $cells.eq(4).hide(); 
     $cells.eq(0).attr("rowspan",3); 
    } else { 
     $cells.eq(2).hide(); 
     $cells.eq(0).attr("rowspan",2); 
    } 

} else if ($cells.eq(2).text() == $cells.eq(4).text()) { 
    $cells.eq(4).hide(); 
    $cells.eq(2).attr("rowspan",2); 
} 

Esto sin duda podría ser optimizada, esto es sólo rápido y sucio. Definitivamente querrá guardar referencias a las celdas y no llamar al eq tantas veces. Tendría que hacer lo mismo para la 2da columna.

Si la tabla puede cambiar de tamaño, le recomendamos que recorra cada celda de la columna y para cada rango que coincida, oculte las coincidencias y configure rowspan. Relativamente fácil, pero no realmente necesario aquí.

+0

De hecho, tengo una versión bruta que funciona bien. Esperaba optimizarlo. – dremme

+0

Para una tabla estática pequeña, la fuerza bruta va a ser óptima en lo que respecta al rendimiento. Algo más dinámico solo va a agregar sobrecarga. –

+0

Entiendo. Estoy contento con el código de fuerza bruta que ya escribí. Mi razón para publicar esto fue simplemente mi curiosidad detrás de soluciones adicionales. Gracias por su respuesta. – dremme