Creating a JSON Tree from a string hierarchy

后端 未结 3 1788
情深已故
情深已故 2020-12-09 11:16

Given these 4 variables,

var el1 = {name:\'ronaldo\', team: \'europe/spain/realmadrid\'}
var el2 = {name:\'messi\', team: \'europe/spain/barcelona\'}
var el3         


        
相关标签:
3条回答
  • 2020-12-09 12:05

    Create your flat data array and than process on data for finding nested json

    like

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

    and then process this

    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);
    
    }
    
    0 讨论(0)
  • 2020-12-09 12:07

    in case you agree to have children as object/hash instead of array, here is my solution based on Jordan's 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 讨论(0)
  • 2020-12-09 12:15

    It'd be waaay easier if somehow el1-el4 were combined into a single object, like

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

    That way you can at least loop through them quickly when processing.

    It'd also be useful to know why you need to have this stored as a JSON Tree. I mean, not all the nodes are the same kind of thing, right? The first level is continent, then country, then team name, and the leaves are individual soccer players. That's a fairly confusing data structure and I'm not sure how it would be useful. Either way, it may be more useful to translate it into a fielded structure first and then generate the tree.

    Edit: Okay, so I thought about it a bit more and I think maybe something like this may do it.

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

    This creates a JavaScript object. I leave it to you to convert this to JSON.

    Update:

    Yeah, I see that the old script would have always put a record in at the second level even if it already existed. This is the new improved FillTree function:

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

    The easiest way to convert this object into JSON, apparently, is to use JSON.stringify(tree) although apparently this is not uniformly supported (see the JavaScript JSON Page).

    0 讨论(0)
提交回复
热议问题