从字符串层次结构创建JSON树

时间:2010-02-19 07:28:41

标签: javascript json tree hierarchy

鉴于这4个变量,

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

我需要生成这个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
                        }
                    ]
                }
            ]
        }
    ]
}

3 个答案:

答案 0 :(得分:13)

如果某种方式将el1-el4组合成一个对象,那就更容易了,比如

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

这样你至少可以在处理时快速循环它们。

了解为什么需要将其存储为JSON树也很有用。我的意思是,并非所有节点都是同一类型的东西,对吧?第一级是大陆,然后是国家,然后是球队名称,而叶子是单独的足球运动员。这是一个相当混乱的数据结构,我不确定它会如何有用。无论哪种方式,首先将其转换为现场结构然后生成树可能更有用。

修改 好的,所以我想了一下,我想也许这样的事可能会这样做。

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

这会创建一个JavaScript对象。我留给你把它转换成JSON。

<强>更新

是的,我看到旧剧本总是会在第二级录制,即使它已经存在。这是新改进的FillTree功能:

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

显然,将此对象转换为JSON的最简单方法是使用JSON.stringify(tree),但显然这不是统一支持的(see the JavaScript JSON Page)。

答案 1 :(得分:0)

如果您同意将子项作为对象/哈希而不是数组,这是我的解决方案基于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];
    }
}

答案 2 :(得分:0)

创建平面数据数组,然后处理数据以查找嵌套的json

喜欢

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

然后处理此

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

}