2010-02-19 19 views
10

Vor dem Hintergrund dieser 4 Variablen anlegen,einen JSON-Baum aus einer String-Hierarchie

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'} 

ich diese JSON Baumhierarchie produzieren muß,

{ 
    "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 
         } 
        ] 
       } 
      ] 
     } 
    ] 
} 

Antwort

12

Es wäre einfacher, wenn waaay irgendwie el1-EL4 wurden zu einem einzigen Objekt kombiniert, wie

So können Sie zumindest schnell durchlaufen sie bei der Verarbeitung.

Es wäre auch nützlich zu wissen, warum Sie dies als JSON-Baum gespeichert haben müssen. Ich meine, nicht alle Knoten sind die gleiche Sache, oder? Die erste Ebene ist Kontinent, dann Land, dann Teamname, und die Blätter sind einzelne Fußballspieler. Das ist eine ziemlich verwirrende Datenstruktur und ich bin mir nicht sicher, wie es sinnvoll wäre. In jedem Fall kann es sinnvoller sein, es zuerst in eine Feldstruktur zu übersetzen und dann den Baum zu generieren.

Bearbeiten: Okay, also dachte ich darüber ein bisschen mehr nach und ich denke, vielleicht kann so etwas machen.

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) 
} 

Dies erstellt ein JavaScript-Objekt. Ich überlasse es Ihnen, dies in JSON zu konvertieren.

Update:

Ja, ich sehe, dass das alte Skript immer einen Datensatz in sogar auf der zweiten Ebene gesetzt hätte, wenn es bereits existierte. Dies ist die neue, verbesserte FillTree Funktion:

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 }) 
} 

Der einfachste Weg, um dieses Objekt in JSON zu konvertieren, es scheint, ist JSON.stringify(tree) zu verwenden, obwohl offensichtlich ist dies nicht einheitlich unterstützt (see the JavaScript JSON Page).

+0

Dank Jordanien, aber Europa sollte nur 2 Kinder haben (Spanien und England) – user275031

+0

@Dementic danke! Wenn Sie selbst eine großartige Lösung haben, schreiben Sie sie bitte. –

+1

Der Code, den ich geschrieben habe, nimmt die gegebene Eingabe und erzeugt exakt den gewünschten Ausgang. Der einzige Unterschied besteht darin, dass es als eine JavaScript-Struktur ausgegeben wird, die das OP frei zu JSON konvertieren kann, indem er die von ihm gewünschte Methode verwendet. Falls Sie sich wundern, dass es unkonstruktiv ist, jemandes Antwort unkonstruktiv zu kritisieren, ist das keine gute Möglichkeit, sie dazu zu motivieren, eine Ihrer eigenen Fragen zu beantworten. –

0

falls Sie einverstanden sind Kinder als Objekt/Hash zu haben, anstelle von Array, hier ist meine Lösung auf Basis von 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

Ihr flaches Datenfeld erstellen und als Prozess auf Daten für verschachtelte json finden

wie

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

und dann verarbeiten diese

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); 

} 
Verwandte Themen