Converting flat structure to hierarchical

前端 未结 6 1410
感情败类
感情败类 2020-12-05 12:02

I need to create function which will be able to convert flat object to recursive object. Here is my example: I have flat array:

var flatArray = [
    {
              


        
相关标签:
6条回答
  • 2020-12-05 12:09

    I tried to write the algorithm in pseudocode, ended up with JS code that almost works (perhaps some additional validations/checks are needed) but shows the general approach to the problem.

    //Lets separate children (nodes with a parent) from roots (nodes without a parent)
    var children = flatArray.filter(function(object){
        return object.parent !== null;
    });
    
    var roots = flatArray.filter(function(object){
        return object.parent === null;
    });
    
    //And add each child to the nodes tree
    children.foreach(function(child){
        recursiveAdd(roots, child);
    });
    
    //To add a children node, node tree is searched recursively for a parent
    function recursiveAdd(nodes, child){
        nodes.foreach(function(parent){
            if(parent.guid === child.parent){
                parent.Children = parent.Children | [];
                parent.Children.add(child);
            } else if(parent.Children) {
                recursiveAdd(parent.Children, child);
            }
        });
    }
    
    //Temporary children array can be garbage collected
    children = null;
    //Resulting node tree
    var recursiveArray = roots;
    
    0 讨论(0)
  • 2020-12-05 12:12

    This one works nicely and is easy to read:

    function flatToHierarchy (flat) {
    
        var roots = [] // things without parent
    
        // make them accessible by guid on this map
        var all = {}
    
        flat.forEach(function(item) {
          all[item.guid] = item
        })
    
        // connect childrens to its parent, and split roots apart
        Object.keys(all).forEach(function (guid) {
            var item = all[guid]
            if (item.parent === null) {
                roots.push(item)
            } else if (item.parent in all) {
                var p = all[item.parent]
                if (!('Children' in p)) {
                    p.Children = []
                }
                p.Children.push(item)
            }
        })
    
        // done!
        return roots
    }
    
    0 讨论(0)
  • 2020-12-05 12:23

    This is how I would do it:

    var flatArray = [{
        Description: "G",
        guid: "c8e63b35",
        parent: null,
    }, {
        Description: "Z",
        guid: "b1113b35",
        parent: "c8e63b35",
    }, {
        Description: "F",
        guid: "d2cc2233",
        parent: "b1113b35",
    }, {
        Description: "L",
        guid: "a24a3b1a",
        parent: null,
    }, {
        Description: "K",
        guid: "cd3b11caa",
        parent: "a24a3b1a",
    }];
    
    var recursiveArray = unflatten(flatArray);
    
    alert(JSON.stringify(recursiveArray, null, 4));
    <script>
    function unflatten(items) {
        return items.reduce(insert, {
            res: [],
            map: {}
        }).res;
    }
    
    function insert(obj, item) {
        var parent     = item.parent;
        var map        = obj.map;
        map[item.guid] = item;
    
        if (parent === null) obj.res.push(item);
        else {
            var parentItem = map[parent];
    
            if (parentItem.hasOwnProperty("Children"))
                parentItem.Children.push(item);
            else parentItem.Children = [item];
        }
    
        return obj;
    }
    </script>

    Of course, this only works if your flatArray has the property that every parent appears before its children.

    Hope that helps.

    0 讨论(0)
  • 2020-12-05 12:24

    you can use bellow code in Angular.

    flatToHierarchy(flat: any[], parent: any = null, Key: string = 'id', parentKey: string = 'parentId') {
      var leafs: any = [];
    
      if (!parent) {
        leafs = flat.filter((x: { [x: string]: any; }) => x[parentKey] === null);
      } else {
        leafs = flat.filter((x: { [x: string]: any; }) => x[parentKey] === parent[Key]);
      }
    
      if (!leafs || leafs.length == 0) {
        return;
      } else {
          leafs.forEach((item: { children: any[]; }) => {
          item.children = [];
          item.children = this.flatToHierarchy(flat, item);
        });
      }
      return leafs;
    }
    

    use same like this

     this.flatToHierarchy(flatItems);
    
    0 讨论(0)
  • 2020-12-05 12:26

    var flatArray = [
        {
            Description: "G",
            guid: "c8e63b35",
            parent: null,
        },
        {
            Description: "Z",
            guid: "b1113b35",
            parent: "c8e63b35",
        },
        {
            Description: "F",
            guid: "d2cc2233",
            parent: "b1113b35",
        },
        {
            Description: "L",
            guid: "a24a3b1a",
            parent: null,
        },
        {
            Description: "K",
            guid: "cd3b11caa",
            parent: "a24a3b1a",
        },      
    ];
    
    //for printing
    function htmlPrint(obj) {
      document.write('<pre>'+JSON.stringify(obj,null,2)+'</pre>');
    };
    
    var guids = {};
    var roots = [];
    
    flatArray.forEach(function(node){ 
      guids[node.guid] = node;       //save into a hash
      node.Children = [];            //make sure it has a children array
      //save it as root if it is a root
      if(node.parent === null){ roots.push(node);}
    });
    flatArray.forEach(function(node){ 
      //if it has a parent, add self to parent's children
      var parent = guids[node.parent]; 
      if(parent)  parent.Children.push(node); 
    });
    htmlPrint(roots);

    0 讨论(0)
  • 2020-12-05 12:31

    This recursive function can be good for you:

    var flatArray = [{
      Description: "G",
      guid: "c8e63b35",
      parent: null,
      Children: []
    }, {
      Description: "Z",
      guid: "b1113b35",
      parent: "c8e63b35",
      Children: []
    }, {
      Description: "F",
      guid: "d2cc2233",
      parent: "b1113b35",
      Children: []
    }, {
      Description: "L",
      guid: "a24a3b1a",
      parent: null,
      Children: []
    }, {
      Description: "K",
      guid: "cd3b11caa",
      parent: "a24a3b1a",
      Children: []
    }, ];
    
    
    
    
    for (var i = 0; i < flatArray.length; i++) {
      recursive(flatArray[i]);
    }
    
    
    function recursive(a) {
      for (var i = 0; i < flatArray.length; i++) {
        if (flatArray[i].parent == a.guid) {
          var b = flatArray[i];
          recursive(b);
          a.Children.push(b);
        }
      }
    }
    
    
    console.log(flatArray)

    0 讨论(0)
提交回复
热议问题