简体   繁体   中英

Convert a list of objects to a json tree structure

I have a list which needs to be converted to a json format.

This..

var sourceList = [
    { title: "item-1", indent: "0" },
    { title: "item-2", indent: "0" },
    { title: "item-3", indent: "0", folder: true },
    { title: "item-4", indent: "1" },
    { title: "item-5", indent: "1", folder: true },
    { title: "item-6", indent: "2" },
    { title: "item-7", indent: "2" },
    { title: "item-8", indent: "0" }
];

to this..

var targetJson = [
    { title: "item-1" },
    { title: "item-2" },
    { title: "item-3", folder: true, children: [
        { title: "item-4" },
        { title: "item-5", folder: true, children: [
            { title: "item-6" },
            { title: "item-7" }
        ]},
    ]},
    { title: "item-8" }
];

so that the result can be used to init a tree structure like below.

    item-1
    item-2
    item-3
    .. item-4
    .. item-5
    .... item-6
    .... item-7
    item-8

The 'indent' property of each source object determines its position relative to the previous object.

Like if an object has indent greater than previous one, then it will be taken as child of previous and if it has indent same as previous then it is taken as sibling of the previous. So children property and folder property will occur for nodes which has sub-items.

One of the challenges would be 'item-8' which is at level-0 than the previous one at level-2.

Need a solution, preferably in javascript.

I kept a mapping between indentation and the element to add children to:

// test data
var sourceList = [
    { title: "item-1", indent: "0" },
    { title: "item-2", indent: "0" },
    { title: "item-3", indent: "0", folder: true },
    { title: "item-4", indent: "1" },
    { title: "item-5", indent: "1", folder: true },
    { title: "item-6", indent: "2" },
    { title: "item-7", indent: "2" },
    { title: "item-8", indent: "0" }
];

// init
var targetJson = [];
var roots = { 0 : targetJson};

// actual code:
sourceList.forEach(function(item){
  if (!roots[item.indent].splice) {
    roots[item.indent] = roots[item.indent].children = [];
  }
  roots[item.indent].push(item);
  if (item.folder) {
    roots[+item.indent+1] = item;
  }
});

// output
console.log(targetJson);

PS: i kept the indent property in the object so you can check the results. Feel free to remove it after the item is added. It is inconsequential.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM