Foros del Web » Programando para Internet » PHP »

Ordenar y presentar Arrays para una índice de libros

Estas en el tema de Ordenar y presentar Arrays para una índice de libros en el foro de PHP en Foros del Web. Hola, estoy haciendo una base de datos de libros, y tengo problemas a la hora de presentar el índice del libro, puesto que hay capítulos ...
  #1 (permalink)  
Antiguo 28/07/2011, 08:25
 
Fecha de Ingreso: diciembre-2009
Ubicación: Madrid
Mensajes: 16
Antigüedad: 14 años, 4 meses
Puntos: 0
Ordenar y presentar Arrays para una índice de libros

Hola,
estoy haciendo una base de datos de libros, y tengo problemas a la hora de presentar el índice del libro, puesto que hay capítulos y "subcapítulos"; no sé cómo sacar los datos en PHP del Array. Primero pondré un ejemplo de lo me gustaría obtener, y luego los problemas que tengo para ello. A ver si me explico bien jjejej

Ejemplo de un índice de un libro:
1.- Estudio en Escarlata (ID=1)
2.- Las Aventuras de Sherlock Holmes (ID=2)
1.- Escándalo en Bohemia (ID=3)
2.- Los Bailarines (ID=4)
3.- El Retorno de Sherlock Holmes (ID=5)

La Base de datos tiene esta tabla de Books_Works, que relaciona el libro (omito su ID por obvia) y el texto (Las Aventuras..., Escándalo Bohemia..., Estudio Escarlata...):

Parent | Order | Work_ID

De acuerdo con el ejemplo, estaría rellenada así:
Parent | Order | ID
0 | 1 | 1
0 | 2 | 2
2 | 1 | 3
2 | 2 | 4
0 | 3 | 5

¿Se entiende el concepto de Parent ("subcapítulo") y Order?

El problema es cuando intento sacar los datos del Array, no se me ocurre un código para decir que con cada $item del Array busque si hay algún otro que tenga de "Parent" su ID (es decir, si hay subcapítulos como en el caso de Las Aventuras...)

He probado con [URL="http://php.net/manual/es/function.array-search.php"]array_search[/URL], pero he de confesar que no me manejo casi nada con Arrays.
De ahí que no sepa más que sacar los datos de la base de datos ordenados por Parent, Order ASC.

¿Vosotros, que sabréis de arrays bastante más que yo, me echaríais una mano con esto?

Gracias de antemano.
  #2 (permalink)  
Antiguo 28/07/2011, 09:28
Avatar de Eleazan  
Fecha de Ingreso: abril-2008
Ubicación: Ibiza
Mensajes: 1.879
Antigüedad: 16 años
Puntos: 326
Respuesta: Ordenar y presentar Arrays para una índice de libros

no te vale esto?

Código SQL:
Ver original
  1. SELECT * FROM `donde_esta_el_orden` ORDER BY `Parent`, `Order`

Te devolvería los resultados por orden... primero los que tengan el parent más pequeño, luego te los ordena por "order".
  #3 (permalink)  
Antiguo 28/07/2011, 09:57
 
Fecha de Ingreso: diciembre-2009
Ubicación: Madrid
Mensajes: 16
Antigüedad: 14 años, 4 meses
Puntos: 0
Respuesta: Ordenar y presentar Arrays para una índice de libros

Gracias por responder. Sin embargo lo que tú propones (y que yo ya implementé, como menciono hacia el final del post) no saca los resultados de forma lógica. Recuerda la tabla con las entradas:
Cita:
Iniciado por gr0uch0mars Ver Mensaje
De acuerdo con el ejemplo, estaría rellenada así:
Parent | Order | ID
0 | 1 | 1
0 | 2 | 2
2 | 1 | 3
2 | 2 | 4
0 | 3 | 5
¿Ves que el orden de los Parent es: 0,0,2,2,0, porque esos dos doses (ID=3 y 4) son "subcapítulos" del segundo cero (ID=2)? No vale con ordenar Parent ASC, puesto que entre medias van dos items.

Creo que la solución pasa por el Array de salida, pero no sé cómo (independientemente de cómo esté ordenado desde SQL) sacar items específicos del Array, incluso indentando (como está en el ejemplo que he puesto) los subcapítulos...
  #4 (permalink)  
Antiguo 28/07/2011, 10:00
Avatar de Eleazan  
Fecha de Ingreso: abril-2008
Ubicación: Ibiza
Mensajes: 1.879
Antigüedad: 16 años
Puntos: 326
Respuesta: Ordenar y presentar Arrays para una índice de libros

Edit:


No he dicho nada, me he liado yo solo xD
  #5 (permalink)  
Antiguo 28/07/2011, 10:11
Avatar de Eleazan  
Fecha de Ingreso: abril-2008
Ubicación: Ibiza
Mensajes: 1.879
Antigüedad: 16 años
Puntos: 326
Respuesta: Ordenar y presentar Arrays para una índice de libros

¿Algo así te vale?
Código PHP:
function tree_sql($level) {
    global 
$link;
    
$sql "SELECT * FROM `table` WHERE `parent`=$level ORDER BY `order`";
    if(
$r mysql_query($sql)) {
        while ( 
$arr mysql_fetch_array($r)) {
            echo 
"level: $level ->".$arr['id'];
            
tree_sql($arr['id']);
        }   
    }
    return 
0;

Te faltaria un join con la tabla de los nombres :)
  #6 (permalink)  
Antiguo 29/07/2011, 05:45
 
Fecha de Ingreso: diciembre-2009
Ubicación: Madrid
Mensajes: 16
Antigüedad: 14 años, 4 meses
Puntos: 0
Respuesta: Ordenar y presentar Arrays para una índice de libros

Algo así había pensado, pero no recuerdo dónde pregunté algo parecido y me recomendaron una solución que no implicaba tantas queries (una para comprobar si hay un "child" de cada capítulo), mejorando la performance.

A ver qué te parece esta idea, y si se podría afinar un poco:

Sacar TODOS los capítulos, ordenados por Parent, Order ASC:
Parent | Order | ID
0 | 1 | 1
0 | 2 | 2
0 | 3 | 5
2 | 1 | 3
2 | 2 | 4

No saldrían en el orden correcto, pero al menos tendríamos en un array todos los datos necesarios.

Al presentar los datos, seleccionar sólo los que interesan: En un primer foreach seleccionar sólo los que "$item['parent'] = 0", y para cada uno a su vez, uno en que compruebe su hay un "$item['parent'] = $item['ID'] (pero el primer Parent se refiere al del subcapítulo y el segundo al ID del item actual, no el del subcapítulo)

Código PHP:
foreach ($results as $item)
{
    
// Seleccionar solo los que tienen Parent = 0
    
if ($item['parent'] = 0)
    {
        echo 
$item['ID']; // Y mostrar el resto de la información de este capítulo...

        // Repetir para subcapítulos cuyo 'parent' = $item['ID'], ¿¿¿con un while, con otro foreach???
        // Y así sucesivamente (para cada uno comprobar si en el array hay alguno cuyo Parent coincida con el ID actual...
    
}

  #7 (permalink)  
Antiguo 29/07/2011, 05:57
Avatar de vgonga1986  
Fecha de Ingreso: marzo-2008
Ubicación: País de Pandereta
Mensajes: 1.021
Antigüedad: 16 años, 1 mes
Puntos: 253
Respuesta: Ordenar y presentar Arrays para una índice de libros

Yo tengo una pregunta: el orden del ID te garantiza el orden de aparición en el índice? Es decir, usando tu ejemplo, esto es posible?

Ejemplo de un índice de un libro:
1.- Estudio en Escarlata (ID=1)
2.- Las Aventuras de Sherlock Holmes (ID=3)

1.- Escándalo en Bohemia (ID=2)
2.- Los Bailarines (ID=4)

3.- El Retorno de Sherlock Holmes (ID=5)

Si eso no es posible y el ID define el orden del índice, la cosa se simplifica mucho. Si me lo confirmas, te pongo un pseudocódigo.

Un saludo.
__________________
¿Alguna pregunta, duda, acotación, nota, cuestión, reparo, comentario, demanda, crítica, interpretación, objeción, interrogante, discrepancia, observación, réplica, disquisición, apostilla o exégesis?
  #8 (permalink)  
Antiguo 29/07/2011, 06:29
 
Fecha de Ingreso: diciembre-2009
Ubicación: Madrid
Mensajes: 16
Antigüedad: 14 años, 4 meses
Puntos: 0
Respuesta: Ordenar y presentar Arrays para una índice de libros

Cita:
Iniciado por vgonga1986 Ver Mensaje
Yo tengo una pregunta: el orden del ID te garantiza el orden de aparición en el índice? Es decir, usando tu ejemplo, esto es posible?

Ejemplo de un índice de un libro:
1.- Estudio en Escarlata (ID=1)
2.- Las Aventuras de Sherlock Holmes (ID=3)

1.- Escándalo en Bohemia (ID=2)
2.- Los Bailarines (ID=4)

3.- El Retorno de Sherlock Holmes (ID=5)

Si eso no es posible y el ID define el orden del índice, la cosa se simplifica mucho. Si me lo confirmas, te pongo un pseudocódigo.

Un saludo.
Por desgracia pasará que el ID no defina el orden, porque puede haber un capítulo con ID muy alta que contenga un subcapítulo de ID muy baja, y entonces el orden ya no es por ID...

Última edición por gr0uch0mars; 29/07/2011 a las 06:29 Razón: Cito el mensaje al que se refiera
  #9 (permalink)  
Antiguo 29/07/2011, 07:21
Avatar de vgonga1986  
Fecha de Ingreso: marzo-2008
Ubicación: País de Pandereta
Mensajes: 1.021
Antigüedad: 16 años, 1 mes
Puntos: 253
Respuesta: Ordenar y presentar Arrays para una índice de libros

Buenas de nuevo.

Eso complica un poco el tema, pero ya me lo imaginaba. De todas formas, te pregunto otra cosilla: puedes modificar la base de datos y el formulario de alta? Si es así, yo añadiría a la tabla un campo llamado level, de forma que tuviéramos un level=0 para el primer orden de título, level=1 para el segundo y así de forma prograsiva. A la hora de añadir un nuevo subtítulo tendrías que añadirlo con nivel = nivel_padre + 1.

Parecen ganas de complicarse la vida, pero si lo haces así, la consulta se te queda muy simple, ya que tu ordenación sería simplemente ORDER BY level, order.

Luego sólo tendrías que llevar una variable en el bucle de lectura que almacenara el $level de la iteracción anterior y, si cambia, sabes que estás en uno nuevo. Es decir, algo así:
Código PHP:
$level = -1
while (/*bucle que recorre el array del SELECT almacenado en $result*/) {
    if (
$level != $result['level']) {
        echo 
"aquí pegamos un salto de nivel, hacer lo que se quiera, por ejemplo, meter un tabulador";
    }
    echo 
"mostrar datos del capítulo";
    
$level $result['level'];

No es exactamente la solución que esperabas, pero es lo más rápido y sencillo que se me ha ocurrido. Creo que compensa sobradamente añadir el campo level contra ejecutar varios bucles para la ordenación correcta del array de resultados.

Un saludo, espero que te sirva, ha sido un problema interesante cuanto menos.
__________________
¿Alguna pregunta, duda, acotación, nota, cuestión, reparo, comentario, demanda, crítica, interpretación, objeción, interrogante, discrepancia, observación, réplica, disquisición, apostilla o exégesis?
  #10 (permalink)  
Antiguo 29/07/2011, 08:03
 
Fecha de Ingreso: diciembre-2009
Ubicación: Madrid
Mensajes: 16
Antigüedad: 14 años, 4 meses
Puntos: 0
Respuesta: Ordenar y presentar Arrays para una índice de libros

Cita:
Iniciado por vgonga1986 Ver Mensaje
Si es así, yo añadiría a la tabla un campo llamado level, de forma que tuviéramos un level=0 para el primer orden de título, level=1 para el segundo y así de forma prograsiva. A la hora de añadir un nuevo subtítulo tendrías que añadirlo con nivel = nivel_padre + 1.
Gracias por la idea. Pero ¿esto no sería un equivalente al "Parent"? (la única diferencia es que con Parent hago una relación directa con otro "ID", mientras que con Level simplemente menciona el nivel de indentación/lista...)

Me explico. Aún cambiando la tabla (no tengo problema en editar la base de datos porque de hecho la estoy haciendo nueva) a:
Level | Order | ID
0 | 1 | 1
0 | 2 | 2
1 | 1 | 3
1 | 2 | 4
0 | 3 | 5

seguiríamos teniendo el problema de que al ordenar por Level, Order ASC, el 5º ítem (que tendría que salir 5º) saldría como 3º, dejando a los de Level 1 (en realidad subcapítulos del 2º ítem) al final. No sé si me explico.

Cita:
Iniciado por vgonga1986 Ver Mensaje
Un saludo, espero que te sirva, ha sido un problema interesante cuanto menos.
mmm, ¿esto significa que abandonas el problema? Gracias de todas formas por los consejos e ideas, vgonga.
  #11 (permalink)  
Antiguo 29/07/2011, 08:50
Avatar de vgonga1986  
Fecha de Ingreso: marzo-2008
Ubicación: País de Pandereta
Mensajes: 1.021
Antigüedad: 16 años, 1 mes
Puntos: 253
Respuesta: Ordenar y presentar Arrays para una índice de libros

Buenas,

No dejo el problema, pero me fui a comer (estoy en el curre). Y tienes toda la razón, me lie al ponerte eso, evidentemente, como tú bien dices, el orden no es el que yo te he dicho.

Déjame que lo piense un poco y a ver si puedo montarlo, más o menos. Tengo hasta las 6, que termino turno, jejeje...

Un saludo.
__________________
¿Alguna pregunta, duda, acotación, nota, cuestión, reparo, comentario, demanda, crítica, interpretación, objeción, interrogante, discrepancia, observación, réplica, disquisición, apostilla o exégesis?
  #12 (permalink)  
Antiguo 29/07/2011, 10:13
Avatar de vgonga1986  
Fecha de Ingreso: marzo-2008
Ubicación: País de Pandereta
Mensajes: 1.021
Antigüedad: 16 años, 1 mes
Puntos: 253
Respuesta: Ordenar y presentar Arrays para una índice de libros

Buenas,

Llevo un rato pensando y la verdad es que no es un tema sencillo. Yo creo que la forma más sencilla es utilizar una función recursiva que vaya haciendo consultas parciales a la base de datos según el nivel de profundidad y vaya montando el contenido final.

Claro está, si sabes algo de informática, que una función recursiva siempre se puede convertir en una función no recursiva. Es lo que he estado intentando, pero este paso no siempre es sencillo y creo que en este caso no lo es para nada.

Ahora me piro a casa, lo voy a ir pensando en el metro, si no se me ocurre la solución no recursiva, te doy los pasos para una recursiva.

Un saludo.
__________________
¿Alguna pregunta, duda, acotación, nota, cuestión, reparo, comentario, demanda, crítica, interpretación, objeción, interrogante, discrepancia, observación, réplica, disquisición, apostilla o exégesis?
  #13 (permalink)  
Antiguo 29/07/2011, 11:46
 
Fecha de Ingreso: diciembre-2009
Ubicación: Madrid
Mensajes: 16
Antigüedad: 14 años, 4 meses
Puntos: 0
Respuesta: Ordenar y presentar Arrays para una índice de libros

Gracias por tu ayuda, y por cierto no hay prisa o sea q no hace falta que te quemes la cabeza con esto de los arrays... jejeje

Lo que pasa es que un libro puede contener muchos capítulos (y de hecho la base de datos también contiene audios, películas... y todos pasarían por la misma función/problema si no una parecida...) y no me gusta que se tenga que hacer una consulta para cada una de las entradas (que es algo que podría hacer yo también), puesto que eso afectaría bastante a la performance de la página (lo siento pero ahora no me sale la traducción de performance en español).

Por eso mi intención es sacar todos los datos en un array y seleccionar de ahí los que me interesan, pero no sé cómo hacerlo (ya avisé que soy ignorante en cuanto a arrays se refiere)

Puedo buscar un código que usé para una web anterior que sacaba las tomas de las canciones, mostrando en una <ul> primero la canción y como sublista las tomas que pertenecían a esa canción. A ver si esta noche lo encuentro y lo cuelgo, que por dar ideas que no sea...

Bueno, me piro. Esta noche busco eso, y gracias por tu ayuda.
  #14 (permalink)  
Antiguo 30/07/2011, 03:54
Avatar de Eleazan  
Fecha de Ingreso: abril-2008
Ubicación: Ibiza
Mensajes: 1.879
Antigüedad: 16 años
Puntos: 326
Respuesta: Ordenar y presentar Arrays para una índice de libros

Lo de antes ha sido una "pájara".

Yo miraría de hacer algo así
Código PHP:
$parent 0;
$order1 1;
while(isset(
$array[$parent][$order1])) {
    
//Imprimes el capitulo
    
echo $array[$parent][$order1]['text'];
    
//Order lo seteas a 1
    
$id $array[$parent][$order1]['id'];
    
$order2 1;
    while(isset(
$array[$id][$order2])) { //Si existen subcapitulos, existirá!
        
echo $array[$id][$order2]['text'];
        
$order2++;
    }
    
$order1++;
   } 

Y para generar el array:
Código PHP:

 
while($arr mysql_fetch_array($sql)) {
     
//Obtengo los campos parent, order, id, y nombre del cap (text)
     
$array[$arr['parent']][$arr['order']]['id'] = $arr['id'];
     
$array[$arr['parent']][$arr['order']]['text'] = $arr['text'];
 } 
Así creo q te sirve :)

Última edición por Eleazan; 30/07/2011 a las 04:03
  #15 (permalink)  
Antiguo 30/07/2011, 11:02
 
Fecha de Ingreso: diciembre-2009
Ubicación: Madrid
Mensajes: 16
Antigüedad: 14 años, 4 meses
Puntos: 0
Respuesta: Ordenar y presentar Arrays para una índice de libros

Cita:
Iniciado por Eleazan Ver Mensaje
Así creo q te sirve :)

Jo-jo-jo... funciona perfectamente!!! Eleazan, no sabes cuánto te agradezco la ayuda porque me hago tanto lío con los arrays que nunca sé cómo sacar los datos de ellos.

A ti y a vgonga1986 de nuevo agradeceros la ayuda y espero que no haya sido muy pesado con el tema.

Un saludo,

Miguel

PD: Si algún moderador quiere poner en el título del hilo "Resuelto" o algo así para que la gente lo sepa...

Última edición por gr0uch0mars; 30/07/2011 a las 11:04 Razón: Poner "Resuelto" en el título del hilo
  #16 (permalink)  
Antiguo 01/08/2011, 01:15
Avatar de vgonga1986  
Fecha de Ingreso: marzo-2008
Ubicación: País de Pandereta
Mensajes: 1.021
Antigüedad: 16 años, 1 mes
Puntos: 253
Respuesta: Ordenar y presentar Arrays para una índice de libros

Buenas,

Siento no haber podido contestar el viernes al final, pero se me lio la tarde, jejeje... Me alegro que lo solucionarais.

Un saludo.
__________________
¿Alguna pregunta, duda, acotación, nota, cuestión, reparo, comentario, demanda, crítica, interpretación, objeción, interrogante, discrepancia, observación, réplica, disquisición, apostilla o exégesis?

Etiquetas: arrays
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 21:33.