2010-02-19 14 views
10

Teniendo en cuenta estas 4 variables,Creación de un árbol JSON de una jerarquía cadena

var el1 = {name:'ronaldo', team: 'europe/spain/realmadrid'} 
var el2 = {name:'messi', team: 'europe/spain/barcelona'} 
var el3 = {name:'gerald', team: 'europe/england/liverpool'} 
var el4 = {name:'unknown english', team: 'europe/england'} 

que necesito para producir esta jerarquía de árbol JSON,

{ 
    "text":"europe", 
    "leaf":false, 
    "children":[ 
     { 
      "text":"spain", 
      "leaf":false, 
      "children":[ 
       { 
        "text":"realmadrid", 
        "leaf":false, 
        "children":[ 
         { 
          "text":"ronaldo", 
          "leaf":true 
         } 
        ] 
       }, 
       { 
        "text":"barcelona", 
        "leaf":false, 
        "children":[ 
         { 
          "text":"messi", 
          "leaf":true 
         } 
        ] 
       } 
      ] 
     }, 
     { 
      "text":"england", 
      "leaf":false, 
      "children":[ 
       { 
        "text":"unknown english", 
        "leaf":true 
       }, 
       { 
        "text":"liverpool", 
        "leaf":false, 
        "children":[ 
         { 
          "text":"gerald", 
          "leaf":true 
         } 
        ] 
       } 
      ] 
     } 
    ] 
} 

Respuesta

12

Sería más fácil si de alguna manera MUUCHO el1-EL4 se combinaron en un solo objeto, como

var data = [] 
data[0] = {name:'ronaldo', team: 'europe/spain/realmadrid'} 
data[1] = {name:'messi', team: 'europe/spain/barcelona'} 
data[2] = {name:'gerald', team: 'europe/england/liverpool'} 
data[3] = {name:'unknown english', team: 'europe/england'} 

De esta forma, al menos puede recorrerlos rápidamente durante el procesamiento.

También sería útil saber por qué necesita tener esto almacenado como un árbol JSON. Quiero decir, no todos los nodos son del mismo tipo, ¿verdad? El primer nivel es continente, luego país, luego nombre del equipo, y las hojas son jugadores individuales de fútbol. Esa es una estructura de datos bastante confusa y no estoy seguro de cómo sería útil. De cualquier manera, puede ser más útil traducirlo en una estructura de campo primero y luego generar el árbol.

Edit: Bien, entonces lo pensé un poco más y creo que tal vez algo como esto pueda hacerlo.

var data = []; 
data[0] = {name:'ronaldo', team: 'europe/spain/realmadrid'}; 
data[1] = {name:'messi', team: 'europe/spain/barcelona'}; 
data[2] = {name:'gerald', team: 'europe/england/liverpool'}; 
data[3] = {name:'unknown english', team: 'europe/england'}; 

var tree = {}; 
function fillTree(name,steps) { 
    current = null; 
    for (var y = 0; y < steps.length; y++) { 
     if (y==0) { 
     if (!tree.children||typeof tree.children == 'undefined'){ 
      tree = { text: steps[y], leaf: false, children: [] }; 
     } 
     current = tree.children; 
     } else { 
     current.push({ text: steps[y], leaf: false, children: [] }) 
     current = current[current.length - 1].children; 
     } 
    } 
    current.push({ text: name, leaf: true }) 
} 

for (x=0; x < data.length; x++) { 
    steps =data[x].team.split('/'); 
    fillTree(data[x].name,steps) 
} 

Esto crea un objeto de JavaScript. Te dejo convertir esto a JSON.

Actualización:

Sí, veo que la vieja escritura tendría que poner siempre un registro en el segundo nivel, incluso si ya existía. Esta es la nueva función FillTree mejorada:

var tree = {}; 
function fillTree(name,steps) { 
    var current = null, 
    existing = null, 
    i = 0; 
    for (var y = 0; y < steps.length; y++) { 
     if (y==0) { 
     if (!tree.children||typeof tree.children == 'undefined'){ 
      tree = { text: steps[y], leaf: false, children: [] }; 
     } 
     current = tree.children; 
     } else { 
     existing = null; 
     for (i=0; i < current.length; i++) { 
      if (current[i].text === steps[y]) { 
       existing = current[i]; 
       break; 
      } 
     } 
     if (existing) { 
      current = existing.children; 
     } else { 
      current.push({ text: steps[y], leaf: false, children: [] }); 
      current = current[current.length - 1].children; 
     } 
     } 
    } 
    current.push({ text: name, leaf: true }) 
} 

La manera más fácil de convertir este objeto en JSON, al parecer, es utilizar JSON.stringify(tree) aunque aparentemente esto no está uniformemente soportado (see the JavaScript JSON Page).

+0

Gracias Jordan, pero Europa solo debe tener 2 hijos (España e Inglaterra) – user275031

+0

@Dementic gracias! Si tiene una gran solución usted mismo, por favor publíquela. –

+1

El código que escribí toma la entrada dada y crea exactamente la salida deseada. La única diferencia es que se genera como una estructura JavaScript, que el OP puede convertir a JSON utilizando el método que desee. En caso de que te lo estés preguntando, criticar de manera no constructiva la respuesta de otra persona no es una buena manera de motivarlos para que respondan a una de tus propias preguntas. –

0

en caso de que de acuerdo en que los niños como objeto/de hash en lugar de matriz, aquí está mi solución basada en la de Jordan https://stackoverflow.com/a/2299268/214420

var el1 = {name:'ronaldo', team: 'europe/spain/realmadrid'} 
var el2 = {name:'messi', team: 'europe/spain/barcelona'} 
var el3 = {name:'gerald', team: 'europe/england/liverpool'} 
var el4 = {name:'unknown english', team: 'europe/england'} 

data = [el1,el2,el3,el4] 
tree = {}; 
for(var i =0; i < data.length;i++){ 
    var steps = data[i].team.split('/'); 

    steps.push(data[i].name) 
    var current = tree; 

    for(var j = 0 ; j < steps.length;j++){ 
     var step = steps[j] 
     current.leaf = false; 
     current.children = current.children || {}; 
     current = current.children 
     current[step] = current[step] || {text:step,leaf:true} 
     current = current[step]; 
    } 
} 
0

Crear la matriz plana de datos y de proceso de datos para la búsqueda de JSON anidada

como

[{"itemname": "item1","settingkey": "key1","settingvalue": "value1"}, {"itemname": "item2","settingkey": "key2","settingvalue": "value2"},]; 

y luego procesar este

var keys = Object.keys(dataMap); 

var json = []; 
for (var key in keys) { 
     var innerJson = {}; 
     innerJson["name"] = keys[key]; 
     var innerMap = dataMap[keys[key]]; 

     if (innerMap instanceof Array) { 
      innerJson["size"] = innerMap[0]; 
     } else if (innerMap instanceof Object) { 

      var child = processHirarchiachalData(innerMap); 
      innerJson["children"] = child; 
     } 
     json.push(innerJson); 

} 
Cuestiones relacionadas