Создание дерева JSON из иерархии строк - PullRequest
10 голосов
/ 19 февраля 2010

Учитывая эти 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 ]

13 голосов
/ 19 февраля 2010

Было бы намного проще, если бы 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. Я имею в виду, что не все узлы одинаковы, верно? Первый уровень - континент, затем страна, затем название команды, а листья - отдельные футболисты. Это довольно запутанная структура данных, и я не уверен, насколько это было бы полезно. В любом случае, было бы более полезно сначала преобразовать его в полевую структуру, а затем сгенерировать дерево.

Edit: Итак, я подумал об этом немного больше, и я думаю, что, может быть, что-то подобное может сделать это.

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), хотя, очевидно, это не поддерживается единообразно ( см. Страницу JSON JavaScript * ).

0 голосов
/ 23 февраля 2015

Создайте свой массив плоских данных и обработайте данные для поиска вложенного 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);

}
0 голосов
/ 03 июля 2013

в случае, если вы согласны иметь детей в качестве объекта / хеша вместо массива, вот мое решение, основанное на 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];
    }
}
Джордана
...