Foros del Web » Programando para Internet » PHP »

Ordenar Anidado o pájaro dodo

Estas en el tema de Ordenar Anidado o pájaro dodo en el foro de PHP en Foros del Web. Tengo una tabla: Nombre - Apellido Hugo - Pérez Paco - Pérez Luis - López Pancho - López Con una consulta Código PHP: $Variable  =  ...
  #1 (permalink)  
Antiguo 14/09/2011, 11:07
Avatar de Rafael
Modegráfico
 
Fecha de Ingreso: marzo-2003
Mensajes: 9.028
Antigüedad: 21 años
Puntos: 1826
Ordenar Anidado o pájaro dodo

Tengo una tabla:

Nombre - Apellido
Hugo - Pérez
Paco - Pérez
Luis - López
Pancho - López


Con una consulta

Código PHP:
$Variable SELECT FROM Listado where Prioridad '0' order by ApellidoNombre 
(Prioridad solo es una condición que estoy usando)
y un
Código PHP:
do {
..
$Nombre $Apellido
..
} while (
$Variable
Puedo desplegar

- López Luis
- López Pancho
- Pérez Hugo
- Pérez Paco

Pregunta: ¿Cómo puedo desplegar:

López
- Luis
- Pancho
Pérez
- Hugo
- Paco
?
Supongo que anidando 2 do (dodo) Pero ando limitado en mis conocimientos.

¿Por donde va la cosa?

(copiado de este post)
  #2 (permalink)  
Antiguo 14/09/2011, 11:50
Avatar de GatorV
$this->role('moderador');
 
Fecha de Ingreso: mayo-2006
Ubicación: /home/ams/
Mensajes: 38.567
Antigüedad: 17 años, 10 meses
Puntos: 2135
Respuesta: Ordenar Anidado o pájaro dodo

Tendrías que condicionar el último apellido que mostraste, por ejemplo:
Código PHP:
Ver original
  1. $lastApellido = '';
  2. do {
  3.       $Apellido = $row['apellido'];
  4.       $Nombre = $row['nombre'];
  5.       if ($Apellido != $lastApellido) {
  6.               echo "<h1>$Apellido</h1>";
  7.               $lastApellido = $Apellido;
  8.       }
  9.       echo $Nombre;
  10. } while (..);

Saludos.
  #3 (permalink)  
Antiguo 14/09/2011, 11:55
Avatar de andresdzphp
Colaborador
 
Fecha de Ingreso: julio-2011
Ubicación: $this->Colombia;
Mensajes: 2.749
Antigüedad: 12 años, 8 meses
Puntos: 793
Respuesta: Ordenar Anidado o pájaro dodo

A mi se me ocurre algo así no estoy seguro si es lo que estás buscando.

Código PHP:
Ver original
  1. <?php
  2. $c = mysql_connect('localhost', 'root', '12345');
  3. mysql_select_db('basededatos');
  4. $sql = 'select * from tabla';
  5. $res = mysql_query($sql) or die(mysql_error());
  6.  
  7. $nombres = array();
  8.  
  9. while ($reg = mysql_fetch_array($res)) {
  10.     $nombres[$reg['apellido']][] = $reg['nombre'];
  11. }
  12.  
  13. foreach ($nombres as $c => $apellido) {
  14.     echo "<b>$c</b> <br />";
  15.     foreach ($apellido as $nombre) {
  16.         echo "- $nombre <br/>";
  17.     }
  18. }

Resultado:

López
- Luis
- Pancho
Pérez
- Paco
- Hugo
__________________
Si sabemos como leer e interpretar el manual será mucho más fácil aprender PHP. En lugar de confiar en ejemplos o copiar y pegar - PHP
  #4 (permalink)  
Antiguo 14/09/2011, 21:43
Avatar de Rafael
Modegráfico
 
Fecha de Ingreso: marzo-2003
Mensajes: 9.028
Antigüedad: 21 años
Puntos: 1826
Respuesta: Ordenar Anidado o pájaro dodo

Gracias GatorV, muy sencillo de implementar. Por el momento es lo que voy a usar.

Andrés, gracias también. Voy a estudiar el anidado que pusiste para entenderlo mejor, es por donde se me ocurría que era, así que aunque la otra opción es la que usaré voy a hacer mi tarea y estudiar el script.

Tx.
  #5 (permalink)  
Antiguo 29/11/2011, 18:41
Avatar de Rafael
Modegráfico
 
Fecha de Ingreso: marzo-2003
Mensajes: 9.028
Antigüedad: 21 años
Puntos: 1826
Respuesta: Ordenar Anidado o pájaro dodo

Retomo el tema, para revolver mi cerebro más.

En el ejemplo de andresdzphp,

Código PHP:
$c mysql_connect('localhost''root''12345'); 
1) Abre la conexión... ¿pero qué cosa se guarda en la variable?
y por qué después se usa otra vez, pero al parecer como un array de una sola columna.

Código PHP:
$sql 'select * from tabla';
$res mysql_query($sql) or die(mysql_error()); 
2) En esta parte, ¿$sql recibe realmente un valor? o solo es una cadena de texto para poderla modificar más fácilitoen vez de poner

Código PHP:
$res mysql_query(select from tabla) or die(mysql_error()); 
  #6 (permalink)  
Antiguo 29/11/2011, 20:35
Avatar de GatorV
$this->role('moderador');
 
Fecha de Ingreso: mayo-2006
Ubicación: /home/ams/
Mensajes: 38.567
Antigüedad: 17 años, 10 meses
Puntos: 2135
Respuesta: Ordenar Anidado o pájaro dodo

Se guarda el identificador de conexión, y es lo correcto almacenarlo para usarlo junto a mysql_query.

También es buena práctica almacenar el query en una cadena de texto para luego pasarlo a mysql_query, así puedes hacer algo así:
Código PHP:
Ver original
  1. $res = mysql_query($query) or die("Error en cadena: $query, error: " . mysql_error());

Saludos.
  #7 (permalink)  
Antiguo 30/11/2011, 01:18
Avatar de abimaelrc
Colaborador
 
Fecha de Ingreso: mayo-2009
Ubicación: En el planeta de Puerto Rico
Mensajes: 14.734
Antigüedad: 14 años, 10 meses
Puntos: 1517
Respuesta: Ordenar Anidado o pájaro dodo

Añado, lo que indicas Rafael es correcto, esto
Código PHP:
Ver original
  1. $qry = 'SELECT * FROM tabla';
  2. mysql_query($qry)...
es lo mismo que
Código PHP:
Ver original
  1. mysql_query('SELECT * FROM tabla')...
Lo único que es recomendable guardarlo en variables para que puedas usar la misma cadena varias veces como te demuestra GatorV. La primera pregunta la razón es que es buena práctica el hacerlo, puede que en algún futuro tu quieras usar más de una conexión e indicar que consulta pertenece a qué conexión, como también puedes cerrar la conexión a la base de datos antes de lo que el garbage collactor lo haga por ti. Yo no he tenido la necesidad de hacer esto, pero es una de las cosas que puedes hacer si lo guardas en una variable la conexión.
__________________
Verifica antes de preguntar.
Los verdaderos amigos se hieren con la verdad, para no perderlos con la mentira. - Eugenio Maria de Hostos
  #8 (permalink)  
Antiguo 30/11/2011, 03:16
Avatar de Rafael
Modegráfico
 
Fecha de Ingreso: marzo-2003
Mensajes: 9.028
Antigüedad: 21 años
Puntos: 1826
Respuesta: Ordenar Anidado o pájaro dodo

Ok, voy entendiendo.

Ahora quiero entender un poquito más cómo se construye el array

Si agrego un print_r acá:

Código PHP:
    while ($reg mysql_fetch_array($res)) {
        
$nombres[$reg['apellido']][] = $reg['nombre'];
print_r($reg);
    } 
Lo que descubro es que prácticamente se genera el contendio completo de la bdd,

y después imprimiendo $nombres

Código PHP:
    while ($reg mysql_fetch_array($res)) {
        
$nombres[$reg['apellido']][] = $reg['nombre'];
print_r($nombres);
    } 
lo que tiene es un array de apellidos, con un array de nombres dentro.

Código PHP:
Array
(
    [
López] => Array
        (
            [
0] => Hugo
            
[1] => Paco
        
)

)

Array
(
    [
Pérez] => Array
        (
            [
0] => Luis
            
[1] => Pedro
        
)


Pero no entiendo de dónde se genera el primer array, el de apellidos, ya que nunca dijimos:
Código PHP:
$nombres $reg['apellido']; 
Editado. Bueno creo que ya entendí, que lo primero que generé fué el Key de cada valor.

Y ahora, ¿cómo podría agregar un array superior, por ejemplo Grupos?

Primaria
-López
--Hugo
--Paco


Secundaria
-López
--Juan
-Pérez
--Pedro


¿Algo así?
Código PHP:
$nombres[$reg['Grupo']][] = $reg['Apellido'];
$nombres[$reg['Grupo']][$reg['Apellido'][]; = $reg['Nombre']; 

Última edición por Rafael; 30/11/2011 a las 09:25
  #9 (permalink)  
Antiguo 30/11/2011, 09:37
Avatar de GatorV
$this->role('moderador');
 
Fecha de Ingreso: mayo-2006
Ubicación: /home/ams/
Mensajes: 38.567
Antigüedad: 17 años, 10 meses
Puntos: 2135
Respuesta: Ordenar Anidado o pájaro dodo

Pues podrías hacerlo así:
Código PHP:
Ver original
  1. $nombres = array();
  2. while ($reg = mysql_fetch_array($res)) {
  3.      if( !isset($nombres[$reg['Grupo']])) $nombres[$reg['Grupo']] = array();
  4.      if( !isset($nombres[$reg['Grupo']][$reg['Apellido']])) $nombres[$reg['Grupo']][$reg['Apellido']] = array();
  5.      $nombres[$reg['Grupo']][$reg['Apellido']] = $reg['Nombre'];
  6. }
  7.  
  8. var_dump($nombres);
  #10 (permalink)  
Antiguo 30/11/2011, 12:21
Avatar de Rafael
Modegráfico
 
Fecha de Ingreso: marzo-2003
Mensajes: 9.028
Antigüedad: 21 años
Puntos: 1826
Respuesta: Ordenar Anidado o pájaro dodo

Le estoy entendiendo un poquito más. Me quedo con tarea.
Pero yo creo que voy a ver la alternativa del array para otro caso, ya que la alternativa que usé fué la de condicionar el Apellido.

(Lo que pususte GatorV)
Código PHP:
    do {
          
$Apellido $row['apellido'];
          
$Nombre $row['nombre'];
          if (
$Apellido != $lastApellido) {
                  echo 
"<h2>$Apellido</h2>";
                  
$lastApellido $Apellido;
          }
          echo <
p>$Nombre</p>;
    } while (..); 
que me funcionó bien.

Solo que me salió una duda.

En este caso se me genera un <h2> seguido de varios <p>
<h2>
<p>
<p>

Pero necesito que se genere un div contenedor al rededor del grupo
<div>
<h2>
<p>
<p>
</div>

La etiqueta de apertura evidentemente no tiene problema, la meto en el primer echo

Código PHP:
echo "<div><h2>$Apellido</h2>"
Pero la de cierre siempre acabo con esto:

<div>
<h2>
<p>
</div>
<p>
</div>

Pregunta, ¿cómo puedo cerrar el div una sola vez?


Necesito seguir usando esta estructura do while conteniendo todo ya que adentro el script ya se volvió muy elaborado. Y ya me entendí solito
  #11 (permalink)  
Antiguo 30/11/2011, 12:29
 
Fecha de Ingreso: diciembre-2010
Ubicación: valencia
Mensajes: 203
Antigüedad: 13 años, 3 meses
Puntos: 11
Respuesta: Ordenar Anidado o pájaro dodo

antes del while abres, despues de el cierras. ten en cuenta que el bucle se va a repetir N veces, no puedes cerrar dentro.
  #12 (permalink)  
Antiguo 30/11/2011, 12:52
Avatar de Rafael
Modegráfico
 
Fecha de Ingreso: marzo-2003
Mensajes: 9.028
Antigüedad: 21 años
Puntos: 1826
Respuesta: Ordenar Anidado o pájaro dodo

Quizá pueda cerrarla antes... de plano hacer una barbaridad como

echo "</div><div><h2>$Apellido</h2>";

Y antes de todos los loops abrir ese div vacío...

Porque de plano no creo que se pueda comparar $Apellido con la siguiente iteración del loop, estando dentro del loop actual... ¿o sí?
  #13 (permalink)  
Antiguo 30/11/2011, 13:14
Avatar de Triby
Mod on free time
 
Fecha de Ingreso: agosto-2008
Ubicación: $MX->Gto['León'];
Mensajes: 10.106
Antigüedad: 15 años, 7 meses
Puntos: 2237
Respuesta: Ordenar Anidado o pájaro dodo

Creo que te facilitaria mucho las cosas guardando en array similar al primer ejemplo que pusiste y que es la sugerencia de GatorV, porque despues recorres de una manera sencilla:

Código PHP:
Ver original
  1. foreach($nombres as $grupo => $grupos) {
  2.       echo "<h2>$grupo</h2>";
  3.       // Aqui puedes abrir contenedor para apellidos
  4.       foreach($grupos as $apellido => $nombres2) {
  5.             echo "<h2>$apellido</h2>";
  6.             echo '<ul>';
  7.             foreach($nombres2 as $nombre) {
  8.                    echo "<li>$nombre</li>";
  9.             }
  10.             echo '</ul>';
  11.       }
  12.       // Aqui cierras contenedor para apellidos (si lo creaste)
  13. }
__________________
- León, Guanajuato
- GV-Foto
  #14 (permalink)  
Antiguo 30/11/2011, 13:43
Avatar de Rafael
Modegráfico
 
Fecha de Ingreso: marzo-2003
Mensajes: 9.028
Antigüedad: 21 años
Puntos: 1826
Respuesta: Ordenar Anidado o pájaro dodo

Hum... Voy a comenzar a adaptarlo dentro del array. Ciertamente está bonito el código.

Voy a dejar por unos días mi adefesio de cerrar un div a lo loco... pero ya encontré dónde abrirlo. Me deja uno que otro div vacío por ahí No me digan que sus primeros scipts no fueron unos Frankensteins también.

Pero comenzaré a reescribir esto. Ya me queda más claro... (Claro que al rato estaré igual de perdido)

Gracias
  #15 (permalink)  
Antiguo 30/11/2011, 13:47
 
Fecha de Ingreso: diciembre-2010
Ubicación: valencia
Mensajes: 203
Antigüedad: 13 años, 3 meses
Puntos: 11
Respuesta: Ordenar Anidado o pájaro dodo

aqui te dejo mi codigo, de ejemplo lo pongo creando una lista para cada apellido.

Código PHP:
$resultado = array(array('Nombre' => 'Luis','Apellido' => 'López'),
                   array(
'Nombre' => 'Hugo','Apellido' => 'Pérez'),
                   array(
'Nombre' => 'Pancho','Apellido' => 'López'),
                   array(
'Nombre' => 'Paco','Apellido' => 'Pérez'));

$tmp = array();

foreach(
$resultado as $v)
{
 
$tmp[$v['Apellido']][] = $v;
}

foreach(
$tmp as $k => $v)
{
 echo 
"<b>".$k."</b><ul>";
 foreach(
$v as $vv)
 {
  echo 
"<li>".$vv['Nombre']."</li>";
 }
 echo 
"</ul>";

en la primera respuesta pense que querias meter todo en un mismo tag, por eso te conteste lo de abrir antes y cerrar despues. despues me di cuenta que querias hacerlo independiente.

edito: ahora me doy cuenta que el codigo que te puse es muy similar al que te puso andresdzphp anteriormente.

Última edición por enrique4480; 30/11/2011 a las 14:03
  #16 (permalink)  
Antiguo 30/11/2011, 15:00
Avatar de Rafael
Modegráfico
 
Fecha de Ingreso: marzo-2003
Mensajes: 9.028
Antigüedad: 21 años
Puntos: 1826
Respuesta: Ordenar Anidado o pájaro dodo

Gracias también Enrique.

Lo que noto que me cuesta trabajo entender son las variables temporales, por ejemplo $tmp as $k => $v

La versión de Triby está muy simplificada y con ella entiendo claramente que variable está contendiendo que dato. Pero también voy a revisar tu versión.
  #17 (permalink)  
Antiguo 30/11/2011, 15:30
 
Fecha de Ingreso: diciembre-2010
Ubicación: valencia
Mensajes: 203
Antigüedad: 13 años, 3 meses
Puntos: 11
Respuesta: Ordenar Anidado o pájaro dodo

Te lo explico paso a paso para que lo entiendas bien.

Código PHP:
$tmp = array(); //array temporal

foreach($resultado as $v)
{
 
$tmp[$v['Apellido']][] = $v;  //$v es el array N dentro de $resultado ("emulando" que fuese una consulta).

el array $tmp[$v['Apellido']] crea una key con el apellido, de esta forma todos los nombres del apellido se encuentran en esa key. por ejemplo:

en $tmp['Pérez'] hay 2 arrays que serian Hugo y Paco que se apellidan Pérez.

ahora el otro bucle:

Código PHP:
foreach($tmp as $k => $v
$tmp es el array creado con los datos, $k es el nombre de la key en el array (López y Pérez en este caso) y $v es el array ya agrupado por apellidos.

en el foreach interno

Código PHP:
foreach($v as $vv)  //se recorre cada elemento del array "agrupado".
 
{
  echo 
"<li>".$vv['Nombre']."</li>";
 } 
edito: añado una clase de ejempo que deja el codigo mas limpio y es mas comodo:

Código PHP:
Ver original
  1. class grupos
  2. {
  3.  private $resultado;
  4.  
  5.  function __construct()
  6.  {
  7.   $this->resultado = array();
  8.  }
  9.  
  10.  public function insertar($k,$arr)
  11.  {
  12.   /*
  13.      Añade a $resultado['Apellido'] el nuevo elemento.
  14.      siendo Apellido el apellido de esa persona.
  15.   */
  16.   $this->resultado[$k][] = $arr;
  17.  }
  18.  
  19.  public function obtener($key)
  20.  {
  21.   /*
  22.      Obtener los datos agrupados en un array.
  23.      Para obtener solo los "Pérez", $key = Pérez.
  24.      Si el array no contiene la key $key retorna todos los nombres ordenados.
  25.   */
  26.   if(!array_key_exists($key,$this->resultado))
  27.   {
  28.    return $this->resultado;
  29.   }
  30.   return $this->resultado[$key];
  31.  }
  32. }

ejemplo de uso:

Código PHP:
Ver original
  1. $resultado = array(array('Nombre' => 'Luis','Apellido' => 'López'),
  2.                    array('Nombre' => 'Hugo','Apellido' => 'Pérez'),
  3.                    array('Nombre' => 'Pancho','Apellido' => 'López'),
  4.                    array('Nombre' => 'Pepe','Apellido' => 'Pérez'));
  5.  
  6. $g = new grupos();
  7. //recorremos el array
  8. foreach($resultado as $v)
  9. {
  10.  //añadimos un nuevo elemento
  11.  $g->insertar($v['Apellido'],$v);
  12. }
  13.  
  14. //obtener solo los López
  15. print_r($g->obtener("López"));
  16. //obtener solo los Pérez
  17. print_r($g->obtener("Pérez"));
  18. //obtener todos
  19. print_r($g->obtener("Todos"));
  20. /*

no tiene pq ser asi, son solo ideas.

Última edición por enrique4480; 30/11/2011 a las 16:03
  #18 (permalink)  
Antiguo 30/11/2011, 16:45
Avatar de Triby
Mod on free time
 
Fecha de Ingreso: agosto-2008
Ubicación: $MX->Gto['León'];
Mensajes: 10.106
Antigüedad: 15 años, 7 meses
Puntos: 2237
Respuesta: Ordenar Anidado o pájaro dodo

Rafa, lo de las "variables temporales" es muy sencillo:

foreach($arreglo as $indice => $valor)

foreach = Para cada elemento de:
$arreglo
as = tratarlo como:
$indice = Clave del elemento, no importa si el array es asociativo o numérico
$valor = Esto puede ser cualquier tipo de dato, incluido otro array que puedes recorrer en otro bucle anidado

Lógicamente, la lectura es más clara si usas variables que tienen que ver con el nombre o tipo de dato, pero puedes poner lo que sea.

En el último foreach del ejemplo que sugerí no se usa índice, porque es un array numérico y la posición (clave) de cada elemento no es relevante.
__________________
- León, Guanajuato
- GV-Foto
  #19 (permalink)  
Antiguo 30/11/2011, 16:45
Avatar de Rafael
Modegráfico
 
Fecha de Ingreso: marzo-2003
Mensajes: 9.028
Antigüedad: 21 años
Puntos: 1826
Respuesta: Ordenar Anidado o pájaro dodo

Hum, muy agracecido por el desglose Enrique, voy a jugar con las variantes del modelo y me dejas más tarea .



Edito. Gracias Triby. He estado haciendo print_r justamente para ver el tipo de array generado.

Ya me queda mucho más clara la generación de los arrays. Voy a jugar a anidar arrays uno dentro de otro y tratar de hacerlos inversamente.

Como que un lapsus mental evita que yo un array deje de verlo como una tabla. Aunque sé que pueden ser multidimensionales, entenderlos como loops anidados es un pequeño brinco mental. Hasta ahora solo había trabajado con arrays de 2 y además no asociativos.

Voy a hacer mi tarea

Última edición por Rafael; 30/11/2011 a las 16:54

Etiquetas: tabla, anidados, variables
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

SíEste tema le ha gustado a 1 personas




La zona horaria es GMT -6. Ahora son las 06:04.