Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JavaScript: Find all parents for element in tree recursive

I have a tree somthing like this

var datas = {
    'tree': [
        {
            'name': 'name1',
            'tree': [
                {'name': 'name2'},
                {'name': 'name3'},
                {
                    'name': 'name4',
                    'tree': [
                        {'name': 'name5'},
                        {'name': 'name6'}
                    ]
                },
                {'name': 'name7'}
            ]
        },
        {
            'name': 'name8',
            'tree': [
                {'name': 'name9'}
            ]
        }
    ]
}

I want to find all the parents of the specifig id

for example in the tree demo, if I look for 'name5' I want to find "name1,name4,name5"

I wrote this code but the results wrong and I got the ids of other elements and not the parents only

This is my code

 keys: string[];
  pathFound: boolean = false;
 getLevel(event: iEventBase, id: string, path: string[]): void {
    if (this.pathFound) return;
    event.content.forEach((key) => {
      if (key.id == id) {
        if(!path){
          path =  [];;
        }
        path.push(key.id);
        this.keys = path;
        this.pathFound = true;
        return;
      }
      if (key.type === "page") {
        if(!path){
          path = [];
        }
        path.push(key.id);
        this.getLevel(key, id, path);
      }
    })
  }
}
this.getLevel(state.mainEvent.content.page, event.id, null);
like image 748
24sharon Avatar asked Nov 13 '18 08:11

24sharon


2 Answers

You could use a recursive approach by checking the name and return a new data structure with only the nodes to the wanted object.

function find({ tree = [], ...object }, name) {
    var result;
    if (object.name === name) return object;
    return tree.some(o => result = find(o, name)) && Object.assign({}, object, { tree: [result] });
}

var datas = { tree: [{ name: 'name1', tree: [{ name: 'name2' }, { name: 'name3' }, { name: 'name4', tree: [{ name: 'name5' }, { name: 'name6' }] }, { name: 'name7' }] }, { name: 'name8', tree: [{ name: 'name9' }] }] };

console.log(find(datas, 'name5'));
.as-console-wrapper { max-height: 100% !important; top: 0; }
like image 195
Nina Scholz Avatar answered Oct 20 '22 01:10

Nina Scholz


Perhaps you could take a recursive approach to this problem. The basic idea here is to look down through the tree for a node whose name matches the node name that your looking to find parents for (ie name5).

Once such a node has been found, then return an array, appending the corresponding parent name of the node to the array until the recursion completely unwinds.

So, something along the lines of this should work:

var datas = {
    'tree': [
        {
            'name': 'name1',
            'tree': [
                {'name': 'name2'},
                {'name': 'name3'},
                {
                    'name': 'name4',
                    'tree': [
                        {'name': 'name5'},
                        {'name': 'name6'}
                    ]
                },
                {'name': 'name7'}
            ]
        },
        {
            'name': 'name8',
            'tree': [
                {'name': 'name9'}
            ]
        }
    ]
}

function findParents(node, searchForName) {

  // If current node name matches the search name, return
  // empty array which is the beginning of our parent result
  if(node.name === searchForName) {
    return []
  }
  
  // Otherwise, if this node has a tree field/value, recursively
  // process the nodes in this tree array
  if(Array.isArray(node.tree)) {
  
    for(var treeNode of node.tree) {

      // Recursively process treeNode. If an array result is
      // returned, then add the treeNode.name to that result
      // and return recursively
      const childResult = findParents(treeNode, searchForName)

      if(Array.isArray(childResult)) {
        return [ treeNode.name ].concat( childResult );
      }
    }
  }
}

console.log( findParents(datas, 'name5') )
like image 20
Dacre Denny Avatar answered Oct 20 '22 01:10

Dacre Denny