entre Desarrolladores

Recibe ayuda de expertos

Registrate y pregunta

Es gratis y fácil

Recibe respuestas

Respuestas, votos y comentarios

Vota y selecciona respuestas

Recibe puntos, vota y da la solución

Pregunta

0voto

Duda algoritmo para recorrer estructura en javascript.

Hola, tengo problemas para recorrer una estructura, por ej: (la estructura inicial puede variar)

enter image description here

Y que pueda ir almacenando las relaciones de la siguiente manera en un arreglo:
var relaciones = [
{1,2},
{2,3},
{3,4},
{2,5},
{1,6},
{6,7},
{1,8},
{1,9},
{9,10},
{9,11},
{9,12}
]

Estoy intentando con una función recursiva pero el problema es que no se como hacer para no perder el id del nodo padre. Muchas gracias por su ayuda.

4 Respuestas

1voto

ctapiamori Puntos1050

Modificando un poco el trabajo de @white y con lo que indicas @jonatancastro1, el siguiente codigo podria ayudarte:

http://jsfiddle.net/c00d5yx3/2/

0voto

white comentado

+1 justo tuve la misma idea de enviar al elemento padre como referencia :P

1voto

ctapiamori comentado

Si, publicamos justo al mismo momento, pero buena implementacion. @white, solo retoque un poco tu codigo.

1voto

jonatancastro1 comentado

Muchas gracias @ctapiamori y @white era exactamente lo que quería realizar. le daria la respuesta a ambos pero no se puede creo jejeje.

0voto

Leonardo-Tadei Puntos227320

Hola @jonatancastro1,

la representación de los árboles es mucho más simple si la planteás al revés: qué cada nodo haga referencia a su nodo padre (y la raíz tendrá por regerencia a NULL)

Con esto resolvés sobre todo el problema de la repetición, ya que por ejemplo tu nodo 1 tiene que aparecer 3 veces en vez de aparecer solo una.

De esta manera, además, podés agregar la reerencia al nodo padre en la estructura en que se almacenan los datos reales de cada nodo, en vez de tener que plantear las relaciones por separado.

No es que con tu planteo no se pueda... solo que es un camino más largo.

Saludos!

0voto

ctapiamori Puntos1050

Hola @jonatancastro1,

has mostrado el resultado var relaciones = [{1,2},{2,3},..] pero no has mostrado tu estructura de donde obtener estos datos, solo una imagen que puede servir de referencia, pero no ayuda mucho, puedes indicar cual es la estructura de donde se obtiene los datos, porque no se de que forma iniciar quieres recuperar los datos.

Saludos,

0voto

white comentado

coincido con @ctapiamori, podrias agregar como recibes los datos de tu estructura de acuerdo al árbol n-ary que planteas?

0voto

jonatancastro1 comentado

es un selector de jquery de una lista $('>ul') el cual puede tener anidados en los item otras listas;

Algo así mas o menos es lo que hago:

this.nav_id=0;
this.assignId = function(el, id)
    {
    var object = this;
    el.attr('data-square_menu', id);
    el.each( function(a, b)
    {
          var square_menu = $(this);
          var li = el.find('>li');
          li.each( function(c, d)
          {
                 square_item = $(this);
                 if(square_item.has('>ul'))
                 {
                         var square_sub_menu = square_item.find('>ul');
                         square_sub_menu.each( function(e, f)
                        {
                              //aqui hago la llamada recursiva
                              object.assignId.call(object, $(this), ++object.nav_id);
                         });
                  }
          });
     }); return;
};
this.assignId($('#ulprincipal'), this.nav_id);

0voto

white comentado

Edite mi respuesta, podria ser esto lo que buscas: http://jsfiddle.net/c00d5yx3/ ?

0voto

jonatancastro1 comentado

Hola @white, pues mas o menos es asi, jejeje el asunto es que hay que asignarle un id consecutivo a todos los ul pero a los ul hijos directos añadir una referencia al id del padre y así recursivamente según tu ejemplo quedaría algo asi:

<ul id="main" style="display:none" data-id="1">
    <li></li>
         ...
    <li></li>
    <li>
        <ul data-id="2" data-id-parent="1">
            <li></li>
                          ...
            <li></li>
            <li>
                <ul data-id="3" data-id-parent="2">
                    <li data-id="15"></li>
                    <li data-id="16"></li>
                    <li data-id="17"></li>
                </ul>
            </li>
        </ul>
    </li>
    <li></li>
    <li></li>
    <li>
        <ul data-id="4" data-id-parent="1">
            <li></li>
            <li></li>
            <li>
                <ul data-id="6" data-id-parent="4">
            </li>
            <li></li>
                         ...
            <li></li>
        </ul>
    </li>
</ul>

De antemano muchas gracias por tu ayuda.

0voto

white comentado

solo tendrías que agregar el elemento padre a la funcion recursiva como referencia, y tener una variable como contador, actualize el codigo:

http://jsfiddle.net/c00d5yx3/3/

1voto

white Puntos75880

Hize una funcion solo por entretenimiento, Talvez no sea el mejor método pero logra hacer lo que deseas.

var Edges = function(struct){

    this.edges = [];
    this.root  = [];
    this.put_edge = function(edge)
    {
        this.edges.push(edge);
    };
    this.get = function(node, parent)
    {
        var ctx = this;

        // si el nodo actual es un aray...
        if(node instanceof Array)
        {
            // recorremos el nodo
            node.forEach(function(item){

                // el item de este array es un objeto?
                if(typeof item === 'object')
                {
                    ctx.get(item, parent);
                }

                // guardamos el edge
                else
                {
                    ctx.put_edge.call(ctx, [parent, item])
                }

            });
        }

        // el nodo actual es un objeto
        else if(typeof node === 'object')
        {

            for(var x in node)
            {
                // agregamos el edge si el padre no es 
                // nulo ( nodo principal )
                if(parent !== null)
                    ctx.put_edge.call(ctx, [parent, x]);

                // recursividad
                if(node[x] !== null && typeof node[x] === 'object')
                    ctx.get(node[x], x);

                // agregamos el edge
                else if(node[x] !== null)
                    ctx.put_edge.call(ctx, [x, node[x]]);

            }
        }   
    };

    // verificamos que tenga un solo nodo principal
    if(Object.keys(struct).length > 1)
        throw new Error("estructura invalida");

    this.root = struct[Object.keys(struct)[0]];

    // obtenemos todas las aristas
    this.get.call(this, struct, null);

    // resultado (:
    var ctx = this;

    return new Object
    ({
        result : function(){ return ctx.edges  },
        root   : function(){ return ctx.root  }
    });
};

suponiendo que tienes un objeto asi:

var object = {
    1 : {
        2 : {
            3 : 4,
            5 : null
        },
        6 : 7,
        8 : null,
        9 : {
            10 : null,
            11 : [{
                12 : 13
            }],
            14 : null,
            15 : [16, 17, 18],
        }
    }
};

para usar la función, la sintaxis es la siguiente:

var result = new Edges(object).result();
console.log(result);

el resultado:

[
    ["1", "2"], ["2", "3"], ["3", 4], ["2", "5"], ["1", "6"], ["6", "7"],
    ["1", "8"], ["1", "9"], ["9", "10"], ["9", "11"], ["11", "12"],
    ["12", 13], ["9", "14"], ["9", "15"], ["15", 16], ["15", "17"], ["15", "18"]
]

EDIT: tratandose de Nodos html y jquery, podria requerir menos esfuerzo: http://jsfiddle.net/c00d5yx3/3/

Por favor, accede o regístrate para responder a esta pregunta.

Otras Preguntas y Respuestas


...

Bienvenido a entre Desarrolladores, donde puedes realizar preguntas y recibir respuestas de otros miembros de la comunidad.

Conecta