Foros del Web » Programando para Internet » PHP »

Problemas con recursividad y arrays multidimensionales

Estas en el tema de Problemas con recursividad y arrays multidimensionales en el foro de PHP en Foros del Web. Hola, necesito que a partir de un array multidimensional que representa la jerarquía de un menú de opciones, algunas de las cuales que contienen a ...
  #1 (permalink)  
Antiguo 06/11/2011, 07:55
Avatar de Mikimoto74  
Fecha de Ingreso: enero-2005
Mensajes: 88
Antigüedad: 19 años, 3 meses
Puntos: 2
Problemas con recursividad y arrays multidimensionales

Hola,

necesito que a partir de un array multidimensional que representa la jerarquía de un menú de opciones, algunas de las cuales que contienen a su vez submenús anidados, poder pasarlo todo a un array unidimensional, para realizar un listado.

Cada elemento del array menú es un objeto de stdClass (objeto estándar de php) representando cada opción. Dispone de varias propiedades, como "nombre", "url", etc, y una de las cuales se llama "submenu", que puede contener a su vez un array de opciones (un submenú). Durante el proceso he de añadir una propiedad más a cada objeto opción que indique el nivel del menú en el que se encuentra dicha opción.

El proceso lo he conseguido obtener, pero me falla asignar bien el nivel de jerarquía en el que se encuentra cada opción, que sería desde 0, para las opciones de primer nivel, en adelante.

Este es el código:

Código PHP:
$menu parse_opciones($menu);


  function 
parse_opciones($opciones$nivel 0) {
        
$opciones_parsed = array();
        foreach (
$opciones as $opcion) {
            
$opcion->nivel $nivel;
            
$opciones_parsed[] = $opcion;
            if (
is_array($opcion->submenu) && count($opcion->submenu)) {
                
$submenu $opcion->submenu;
                
$opcion->submenu '';
                
$opciones_parsed array_merge($opciones_parsedparse_opciones($submenu$nivel++));
            }
        }
        return 
$opciones_parsed;
    } 
Os agradecería mucho que me ayudaseis. He conseguido aparentemente lo más difícil, pero lo del nivel aún se me resiste después de darle tantas vueltas.
  #2 (permalink)  
Antiguo 06/11/2011, 08:04
Avatar de Patriarka  
Fecha de Ingreso: enero-2011
Ubicación: Moreno, Buenos Aires, Argentina
Mensajes: 2.851
Antigüedad: 13 años, 3 meses
Puntos: 288
Respuesta: Problemas con recursividad y arrays multidimensionales

como armas el array?
  #3 (permalink)  
Antiguo 06/11/2011, 08:49
Avatar de Mikimoto74  
Fecha de Ingreso: enero-2005
Mensajes: 88
Antigüedad: 19 años, 3 meses
Puntos: 2
Respuesta: Problemas con recursividad y arrays multidimensionales

Pongo el array antes y después, con algunas propiedades quitadas para resumir, y también algunas opciones, así que faltan índices:

Código:
Array
(
    [0] => stdClass Object
        (
            [id_opcion] => 1
            [nombre_es] => Empresa
            [url] => 
            [id_padre] => 0
            [orden] => 1
            [activo] => 1
            [submenu] => Array
                (
                    [0] => stdClass Object
                        (
                            [id_opcion] => 6
                            [nombre_es] => Sobre nosotros
                            [url] => 
                            [id_padre] => 1
                            [orden] => 1
                            [activo] => 1
                            [submenu] => 
                        )

                    [1] => stdClass Object
                        (
                            [id_opcion] => 7
                            [nombre_es] => Historia
                            [url] => #
                            [id_padre] => 1
                            [orden] => 2
                            [activo] => 1
                            [submenu] => 
                        )

                )

        )

    [1] => stdClass Object
        (
            [id_opcion] => 2
            [nombre_es] => Productos
            [url] => 
            [id_padre] => 0
            [orden] => 1
            [activo] => 1
            [submenu] => Array
                (
                    [1] => stdClass Object
                        (
                            [id_opcion] => 14
                            [nombre_es] => Colecciones
                            [url] => 
                            [id_padre] => 2
                            [orden] => 2
                            [activo] => 1
                            [submenu] => Array
                                (
                                    [0] => stdClass Object
                                        (
                                            [id_opcion] => 15
                                            [nombre_es] => Colección 1
                                            [url] => #
                                            [id_padre] => 14
                                            [orden] => 1
                                            [activo] => 1
                                            [submenu] => 
                                        )

                                    [1] => stdClass Object
                                        (
                                            [id_opcion] => 16
                                            [nombre_es] => Colección 2
                                            [url] => #
                                            [id_padre] => 14
                                            [orden] => 2
                                            [activo] => 1
                                            [submenu] => 
                                        )

                                )

                        )

                    [2] => stdClass Object
                        (
                            [id_opcion] => 24
                            [nombre_es] => Accesorios
                            [url] => 
                            [id_padre] => 2
                            [orden] => 3
                            [activo] => 1
                            [submenu] => Array
                                (
                                    [0] => stdClass Object
                                        (
                                            [id_opcion] => 22
                                            [nombre_es] => Colección 1
                                            [url] => #
                                            [id_padre] => 24
                                            [orden] => 1
                                            [activo] => 1
                                            [submenu] => 
                                        )

                                )

                        )

                )

        )

    [2] => stdClass Object
        (
            [id_opcion] => 3
            [nombre_es] => I+D
            [url] => 
            [id_padre] => 0
            [orden] => 1
            [activo] => 1
            [submenu] => Array
                (
                    [0] => stdClass Object
                        (
                            [id_opcion] => 11
                            [nombre_es] => Innovación
                            [url] => #
                            [id_padre] => 3
                            [orden] => 1
                            [activo] => 1
                            [submenu] => 
                        )

                    [1] => stdClass Object
                        (
                            [id_opcion] => 12
                            [nombre_es] => Ideas&Trends
                            [url] => #
                            [id_padre] => 3
                            [orden] => 2
                            [activo] => 1
                            [submenu] => 
                        )

                )

        )

    [4] => stdClass Object
        (
            [id_opcion] => 5
            [nombre_es] => Contacto
            [url] => 
            [id_padre] => 0
            [orden] => 1
            [activo] => 1
            [submenu] => 
        )

)

Código:
Array
(
    [0] => stdClass Object
        (
            [id_opcion] => 1
            [nombre_es] => Empresa
            [url] => 
            [id_padre] => 0
            [orden] => 1
            [activo] => 1
            [submenu] => 
            [nivel] => 0
        )

    [1] => stdClass Object
        (
            [id_opcion] => 6
            [nombre_es] => Sobre nosotros
            [url] => 
            [id_padre] => 1
            [orden] => 1
            [activo] => 1
            [submenu] => 
            [nivel] => 0
        )

    [2] => stdClass Object
        (
            [id_opcion] => 7
            [nombre_es] => Historia
            [url] => #
            [id_padre] => 1
            [orden] => 2
            [activo] => 1
            [submenu] => 
            [nivel] => 0
        )

    [6] => stdClass Object
        (
            [id_opcion] => 2
            [nombre_es] => Productos
            [url] => 
            [id_padre] => 0
            [orden] => 1
            [activo] => 1
            [submenu] => 
            [nivel] => 1
        )

    [8] => stdClass Object
        (
            [id_opcion] => 14
            [nombre_es] => Colecciones
            [url] => 
            [id_padre] => 2
            [orden] => 2
            [activo] => 1
            [submenu] => 
            [nivel] => 1
        )

    [9] => stdClass Object
        (
            [id_opcion] => 15
            [nombre_es] => Colección 1
            [url] => #
            [id_padre] => 14
            [orden] => 1
            [activo] => 1
            [submenu] => 
            [nivel] => 1
        )

    [10] => stdClass Object
        (
            [id_opcion] => 16
            [nombre_es] => Colección 2
            [url] => #
            [id_padre] => 14
            [orden] => 2
            [activo] => 1
            [submenu] => 
            [nivel] => 1
        )

    [18] => stdClass Object
        (
            [id_opcion] => 24
            [nombre_es] => Accesorios
            [url] => 
            [id_padre] => 2
            [orden] => 3
            [activo] => 1
            [submenu] => 
            [nivel] => 2
        )

    [19] => stdClass Object
        (
            [id_opcion] => 22
            [nombre_es] => Colección 1
            [url] => #
            [id_padre] => 24
            [orden] => 1
            [activo] => 1
            [submenu] => 
            [nivel] => 2
        )

    [20] => stdClass Object
        (
            [id_opcion] => 3
            [nombre_es] => I+D
            [url] => 
            [id_padre] => 0
            [orden] => 1
            [activo] => 1
            [submenu] => 
            [nivel] => 2
        )

    [21] => stdClass Object
        (
            [id_opcion] => 11
            [nombre_es] => Innovación
            [url] => #
            [id_padre] => 3
            [orden] => 1
            [activo] => 1
            [submenu] => 
            [nivel] => 2
        )

    [22] => stdClass Object
        (
            [id_opcion] => 12
            [nombre_es] => Ideas&Trends
            [url] => #
            [id_padre] => 3
            [orden] => 2
            [activo] => 1
            [submenu] => 
            [nivel] => 2
        )

    [24] => stdClass Object
        (
            [id_opcion] => 5
            [nombre_es] => Contacto
            [url] => 
            [id_padre] => 0
            [orden] => 1
            [activo] => 1
            [submenu] => 
            [nivel] => 3
        )

)
Como se puede ver, los niveles de profundidad están mal asignados
  #4 (permalink)  
Antiguo 06/11/2011, 09:09
Avatar de Patriarka  
Fecha de Ingreso: enero-2011
Ubicación: Moreno, Buenos Aires, Argentina
Mensajes: 2.851
Antigüedad: 13 años, 3 meses
Puntos: 288
Respuesta: Problemas con recursividad y arrays multidimensionales

yo me guiaria solo por el indice ID_PADRE ya que te dice justamente quien es el padre asi
sabes de donde empezar, ademas el indice submenu ya te dice quienes son los hijos
function recusrsiva(){
foreach($Array as $key => $value){
echo $value;
if(is_array($key['submenu'])){
recusrsiva();
}
}
}

en el manual de php.net hay mejores ejemplos
  #5 (permalink)  
Antiguo 06/11/2011, 13:37
Avatar de Mikimoto74  
Fecha de Ingreso: enero-2005
Mensajes: 88
Antigüedad: 19 años, 3 meses
Puntos: 2
Respuesta: Problemas con recursividad y arrays multidimensionales

emmm,

la función recursiva ya la tengo Patriarka. Has hecho lo que yo, pero de un modo más genérico (además los elementos son objetos, no arrays asociativos). Sólo me queda saber el nivel en el que se encuentra una opción dada. Para esto no puedo basarme en el id_padre porque el id_padre no me dice por sí solo en qué nivel está el padre.
  #6 (permalink)  
Antiguo 06/11/2011, 15:13
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: Problemas con recursividad y arrays multidimensionales

Hola,

Posiblemente,

Cita:
Iniciado por Mikimoto74 Ver Mensaje
... necesito que a partir de un array multidimensional que representa la jerarquía de un menú de opciones, algunas de las cuales que contienen a su vez submenús anidados, poder pasarlo todo a un array unidimensional, para realizar un listado. ...
El problema es que estás usando la misma variable para agregar los valores y cuando regresa de la función recursiva trae todos los valores anteiores mas los nuevos y la lógica se vuelve bastante confusa.

Código:
$menu = parse_opciones($menu);


  function parse_opciones($opciones, $nivel = 0) {
        $opciones_parsed = array();
        foreach ($opciones as $opcion) {
            $opcion->nivel = $nivel;
            $opciones_parsed[] = $opcion;
            if (is_array($opcion->submenu) && count($opcion->submenu)) {
                $submenu = $opcion->submenu;
                $opcion->submenu = '';
                $opciones_parsed = array_merge($opciones_parsed, parse_opciones($submenu, $nivel++));
            }
        }
        return $opciones_parsed;
    }
Seguramente el array_merge, mezcla los valores de $opciones_parsed, con los valores que ya existían y se vuelve un relajo.

Revisa el método renum de este post:
http://www.forosdelweb.com/f18/saber...3/#post3287009
En tu caso son objetos, etc, etc, es simplemente para que observes como puedes adaptar tu código para que funcione.

Saludos,
  #7 (permalink)  
Antiguo 06/11/2011, 16:00
Avatar de Mikimoto74  
Fecha de Ingreso: enero-2005
Mensajes: 88
Antigüedad: 19 años, 3 meses
Puntos: 2
Respuesta: Problemas con recursividad y arrays multidimensionales

Bueno, el problema no está en cómo obtengo los elementos, porque los obtengo justo en el orden que quiero, es decir: primer elemento, sus descendientes, segundo elemento, sus descendientes, etc.

Yo creo que la función la dejaría así en cuanto al recorrido por los elementos del array multidimensional (bueno, mejor dicho combinación de arrays y objetos con anidación), porque ya los obtengo como quiero, pero ya no se me ocurre dónde ubicar o qué hacer con los niveles de profundidad.
  #8 (permalink)  
Antiguo 06/11/2011, 16:38
Avatar de Mikimoto74  
Fecha de Ingreso: enero-2005
Mensajes: 88
Antigüedad: 19 años, 3 meses
Puntos: 2
Respuesta: Problemas con recursividad y arrays multidimensionales

Ya lo tengo!!

Código PHP:
function parse_opciones($opciones$nivel 0) {
        
$opciones_parsed = array();
        foreach (
$opciones as $opcion) {
            
$opcion->nivel $nivel;
            
$opciones_parsed[] = $opcion;
            if (
is_array($opcion->submenu) && count($opcion->submenu)) {
                
$nivel++;
                
$submenu $opcion->submenu;
                
$opcion->submenu '';
                
$opciones_parsed array_merge($opciones_parsedparse_opciones($submenu$nivel));
                
$nivel $nivel 1;
            }
            
        } 
        return 
$opciones_parsed;
    } 
Gracias de todos modos por ayudarme.
  #9 (permalink)  
Antiguo 06/11/2011, 18:32
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: Problemas con recursividad y arrays multidimensionales

Hola,

Que bueno que ya lo resolviste.

Como comentario adicional, no vi el $nivel++ al final de la línea, cuando se pasan valores a los métodos recursivos se pasa $nivel + 1. No aumentas y vuelves a reducir al volver.

Código:
                $opciones_parsed = array_merge($opciones_parsed,
parse_opciones($submenu, $nivel + 1));
Saludos,

ps:

Código:
$nivel = $nivel - 1;
$nivel--;

Etiquetas: arrays, recursividad
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:04.