2

I'm trying to transform my data on client side from this format:

let testLoad=  [{"id":7,"name":"Kuwait","parentId":2},
                    {"id":4,"name":"Iraq","parentId":2},
                    {"id":10,"name":"Qatar","parentId":2},
                    {"id":2,"name":"Middle East","parentId":1},
                    {"id":3,"name":"Bahrain","parentId":2},
                    {"id":6,"name":"Jordan","parentId":2},
                    {"id":8,"name":"Lebanon","parentId":2},
                    {"id":1,"name":"Africa/Middle East","parentId":null},
                    {"id":5,"name":"Israel","parentId":2},
                    {"id":9,"name":"Oman","parentId":2}];

to this format:

   let testLoad=  [{"id":55,"text":"Africa/Middle East","children":[
      {"id":2,"text":"Middle East","children":   [{"id":7,"name":"Kuwait","children":[]},
{"id":4,"name":"Iraq","children":[]},
{"id":10,"name":"Qatar","children":[]},
{"id":3,"name":"Bahrain","children":[]},
{"id":6,"name":"Jordan","children":[]},
{"id":8,"name":"Lebanon","children":[]},
{"id":5,"name":"Israel","children":[]},
{"id":9,"name":"Oman","children":[]}]}]

so I can use it in a tree library like gijgo tree or jstree in javascript.

otto
  • 83
  • 6

4 Answers4

1

You could use recursion :

var testLoad=  [{"id":7,"name":"Kuwait","parentId":2},
                    {"id":4,"name":"Iraq","parentId":2},
                    {"id":10,"name":"Qatar","parentId":2},
                    {"id":2,"name":"Middle East","parentId":1},
                    {"id":3,"name":"Bahrain","parentId":2},
                    {"id":6,"name":"Jordan","parentId":2},
                    {"id":8,"name":"Lebanon","parentId":2},
                    {"id":1,"name":"Africa/Middle East","parentId":null},
                    {"id":5,"name":"Israel","parentId":2},
                    {"id":9,"name":"Oman","parentId":2}];

function lookingForNodeWithParent( nodes, parentId ) {

  var arrayToReturn = [];

  for( var i = 0, length = nodes.length; i < length; i++ ) {
    if( nodes[i].parentId === parentId ) {
     var node = nodes[i];
      
      arrayToReturn.push({
        id: node.id,
        name: node.name,
        childrens: lookingForNodeWithParent( nodes, node.id )
      });
    }
  }
  
  return arrayToReturn;
}

var array = lookingForNodeWithParent( testLoad, null );
console.log( array )
Happyriri
  • 4,295
  • 1
  • 17
  • 28
  • That's great. A very simple and elegant solution. Also I appreciate the naming of the variable – otto Mar 24 '17 at 00:54
0

The easiest way would be to create a map of the items based on their ID.

Example: var objectMap = {5: {"name":"Jordan","children":[], parentId: '2'}}

Then you can iterate on them to build your structure:

for (key in objectMap) {
    var object = objectMap[key];
    var parent = objectMap[parseInt(object.parentId)];
    parent.children.push(object);
}
Joshua J Wilborn
  • 526
  • 3
  • 13
  • I think that only associates the current node to its parent. You also need to know the tree depth and repeat that code for every level to link the tree on all its levels – otto Mar 23 '17 at 17:35
  • If every node gets added to it's parents children, then if there is nesting the path should already follow. – Joshua J Wilborn Mar 23 '17 at 20:17
0

You could collect all nodes an built part trees out of it and get the root note for the tree of the collecting object.

  • It works in a single loop.

  • It works for unsorted data.

  • It builds for any node a node with the given data and takes the parts from the node as parent and a parent node if not exist and put it as a children to it.

var data = [{ id: 7, name: "Kuwait", parentId: 2 }, { id: 4, name: "Iraq", parentId: 2 }, { id: 10, name: "Qatar", parentId: 2 }, { id: 2, name: "Middle East", parentId: 1 }, { id: 3, name: "Bahrain", parentId: 2 }, { id: 6, name: "Jordan", parentId: 2 }, { id: 8, name: "Lebanon", parentId: 2 }, { id: 1, name: "Africa/Middle East", parentId: null }, { id: 5, name: "Israel", parentId: 2 }, { id: 9, name: "Oman", parentId: 2 }],
    tree = function (data, root) {
        var r = [], o = {};
        data.forEach(function (a) {
            a.children = o[a.id] && o[a.id].children || [];
            o[a.id] = a;
            if (a.parentId === root) {
                r.push(a);
            } else {
                o[a.parentId] = o[a.parentId] || {};
                o[a.parentId].children = o[a.parentId].children || [];
                o[a.parentId].children.push(a);
            }
        });
        return r;
    }(data, null);

console.log(tree);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
  • It doesn't work if I have more than one root(parentId == null) in my input data. I verified with an input data object that contains also Asia/Pacific as root object with some other children attached to it. – otto Mar 24 '17 at 00:59
  • But thank you, I mean for the above example works 100%. So this can also solve the problem with some minor tuning – otto Mar 24 '17 at 01:01
0

Yes. You can see an example at http://gijgo.com/tree/demos/bootstrap-treeview. Click on the "Back-End Code" tab in order to see how to do that with Linq or EF in .NET

Atanas Atanasov
  • 377
  • 1
  • 8