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/