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

发布于 2024-08-22 12:25:47 字数 1651 浏览 6 评论 0原文

给定这 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
                        }
                    ]
                }
            ]
        }
    ]
}

Given these 4 variables,

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,

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

維他命╮ 2024-08-29 12:25:47

如果以某种方式将 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) ,尽管显然这并未得到统一支持(查看 JavaScript JSON 页面)。

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

下壹個目標 2024-08-29 12:25:47

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

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];
    }
}
遥远的她 2024-08-29 12:25:47

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

}

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

}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文