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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2294695/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-22 23:38:27  来源:igfitidea点击:

Creating a JSON Tree from a string hierarchy

javascriptjsontreehierarchy

提问by user275031

Given these 4 variables,

鉴于这 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'}

I need to produce this JSON tree hierarchy,

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

回答by Jordan Reiter

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

如果以某种方式将 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'}

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.

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

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.

这将创建一个 JavaScript 对象。我让你把它转换成 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:

是的,我看到旧脚本总是会在第二级放置记录,即使它已经存在。这是新改进的 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 })
}

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

显然,将此对象转换为 JSON 的最简单方法是使用,JSON.stringify(tree)尽管这显然不是统一支持的(请参阅 JavaScript JSON 页面)。

回答by Alireza Eliaderani

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

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

回答by gopesh

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

创建您的平面数据数组,然后处理数据以查找嵌套的 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);

}