0

I have an array of objects from which I would like to group by a property to build a tree structure.

objects = [object1, object2, object3, ... ]

Object example:

object1 = {
           FolderName: "Folder1",  //group on this property
           NodeName: "Node1"
          }

I want to group objects by the FolderName property to get a tree structure like this:

treeData  = [
              {
                text: "Folder1",
                nodes: [
                          {
                            text: "Node1",
                          }
                        ]
              },
              { 
                text: "Folder2",
                nodes : [
                          {
                            text: "NodeX",
                          }
                        ]
              }
            ]

Edit:

I was trying with this groupBy function but it returns an array of arrays. So I transform it into the tree structure I need with the for loop. I got the result I want but I wander how to achieve it in a more optimal way.

function groupBy(array, f) {
      var groups = {};
      array.forEach(function(o){
        var group = JSON.stringify(f(o));
        groups[group] = groups[group] || [];
        groups[group].push(o);
      });
      return Object.keys(groups).map(function(group){
        return groups[group]; 
      });
    }

var result = groupBy(objects, function(item){
    item.text = item.NodeName;
    return [item.FolderName];
});

var treeData = [];
for (i=0; i < result.length; i++) {
     treeData.push({ "text": result[i][0].FolderName, "nodes":result[i]});
}
1
  • This may help you : lodash.com/docs Commented May 4, 2015 at 15:10

1 Answer 1

2

Haven't tested, but try:

var treeData = [],
    folders = {};

objects.forEach(function(obj){
    if(obj.FolderName in folders)
        treeData[folders[obj.FolderName]].nodes.push({text:obj.NodeName});
    else 
        folders[obj.FolderName] = treeData.push({text: obj.FolderName, nodes: [{text:obj.NodeName}]}) - 1;
});

The idea is to create an object (folders) while building the tree array, which stores the FolderName as a property and the index of where that FolderName was added in the treeData array as the value. When adding to the tree, you check if the folder object has this property, and if so, add the node to the nodes array of the object stored at that value.

Sign up to request clarification or add additional context in comments.

5 Comments

Good idea, very simple way to do it
You can also add a fiddle here and I can help to debug. Did you notice the - 1 to get the index? Because .push returns the new length of the array, it has to be reduced by one to get the index of the object added.
After review, your code is working perfectly. Thank you
By the way do you know a good, light, and simple js tree library?
Nah, can't say I do. Good, light, simple libraries are hard to come by for most things!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.