Skip to content Skip to sidebar Skip to footer

Nested Tree Structure Data Generation

please bare with my English and writing question, i have a array of json data which i am trying to make it in a nested tree structure but not getting success , hope someone can hel

Solution 1:

Whew! That was fun.

const data = [ {
  "id" : 1,
  "name" : "Abc",
  "path" : "/",
  "type" : "folder"
}, {
  "id" : 2,
  "name" : "Xyz",
  "path" : "/Abc/",
  "type" : "folder"
}, {
  "id" : 3,
  "name" : "Pqr",
  "path" : "/Abc/Xyz/",
  "type" : "folder"
}, {
  "id" : 4,
  "name" : "Zap", 
  "path" : "/Abc/Xyz/Pqr/",
  "type" : "folder"
 },{
  "id" : 5,
  "name" : "file1", 
  "path" : "/Abc/Xyz/Pqr/",
  "type" : "file"
},{
  "id" : 6,
  "name" : "file2", 
  "path" : "/Abc/Xyz/Pqr/",
  "type" : "file"
},{
  "id" : 7,
  "name" : "file3", 
  "path" : "/Abc/Xyz/",
  "type" : "file"
},{
  "id" : 8,
  "name" : "file4", 
  "path" : "/Abc/Xyz/Pqr/Zap/",
  "type" : "file"
}]

const pathPartRegex = /.*?\//g;
const tree = _.reduce(data, (result, value) => {
    const pathParts = value.path.match(pathPartRegex);
    let node = result;
    let path = "";

    // Go down through tree until last path part
    const notLastPart = pathParts.splice(0, pathParts.length - 1);
    for (const pathPart of notLastPart) {
        path += pathPart;
        const existingNode = node.children 
                                ? node.children.find(item => item.path === path)
                                : node.find(item => item.path === path);
        if (existingNode) {
            node = existingNode
        } else {
            // If we need to traverse over a path that doesn't exist, just create it
            // See notes 
            const newNode = {
                path: path,
                children: []
            };

            // The root element is just an array, and doesn't have a children property
            if (node.children) {
                node.children.push(newNode);
            } else {
                node.push(newNode);
            }
            node = newNode;
        }
    }

    // Add new node
    const newNode = {
        id: value.id,
        name: value.name,
        type: value.type,
        path: value.path,
        children: []
    };

    // The root element is just an array, and doesn't have a children property
    if (node.children) {
        node.children.push(newNode);
    } else {
        node.push(newNode);
    }

    return result;
}, []);

Tested via RunKit (https://npm.runkit.com/lodash)


Notes:

The sample data set does not cover how to handle a situation where the "parent" path is not defined at all:

const data = [{
  "id" : 1,
  "name" : "Abc",
  "path" : "/",
  "type" : "folder"
}, {
  "id" : 3,
  "name" : "Pqr",
  "path" : "/Abc/Xyz/",
  "type" : "folder"
}];

Nor a situation where the "parent" path is defined after the child:

const data = [{
  "id" : 1,
  "name" : "Abc",
  "path" : "/",
  "type" : "folder"
}, {
  "id" : 3,
  "name" : "Pqr",
  "path" : "/Abc/Xyz/",
  "type" : "folder"
}, {
  "id" : 2,
  "name" : "Xyz",
  "path" : "/Abc/",
  "type" : "folder"
}];

The code I wrote will handle these, but may create nodes without an id property. If you need to handle situations like that, you can either fix the input data beforehand or modify this code to handle those situations.


Solution 2:

The answer which i also got working is something like this:

const sts=_.memoize(function(){ return []; });
const result = _.filter(folderdata, function(item){
  let parentName = '';
  if(item.path != '/')parentName = item.path;
  item.children = sts(item.path+item.name+'/');
  if (item.type == 'folder') return !(parentName && sts(parentName).push(item));
});

Post a Comment for "Nested Tree Structure Data Generation"