Javascript: deep find object in tree, then return object and the path to it through the tree - Stack Overflow

I've got a data structure that looks something like this:let tree = {id: 1,name: "Some Name&q

I've got a data structure that looks something like this:

let tree = {
  id: 1,
  name: "Some Name",
  children: [
    {
      id: 2,
      name: "Child 1",
      children: [...more nested objects...]
    }
  ]
};

I've written a recursive function to find a given object within that tree, but I now need to also return the path through the tree to the object that is returned. I'm trying to figure out how to modify my search function to do this.

Search function:

_findInTree = (id, tree) => {
    let result;
    if (tree.id === id) {
      result = tree;
    } else {
      for (let child of tree.children) {
        if (child.id === id) { result = child; }
        result = this._findInTree(id, child);
        if (result) { break; }
      }
    }
    return result;
  }

I've got a data structure that looks something like this:

let tree = {
  id: 1,
  name: "Some Name",
  children: [
    {
      id: 2,
      name: "Child 1",
      children: [...more nested objects...]
    }
  ]
};

I've written a recursive function to find a given object within that tree, but I now need to also return the path through the tree to the object that is returned. I'm trying to figure out how to modify my search function to do this.

Search function:

_findInTree = (id, tree) => {
    let result;
    if (tree.id === id) {
      result = tree;
    } else {
      for (let child of tree.children) {
        if (child.id === id) { result = child; }
        result = this._findInTree(id, child);
        if (result) { break; }
      }
    }
    return result;
  }
Share Improve this question edited Oct 3, 2018 at 2:40 Machavity 31.7k27 gold badges95 silver badges105 bronze badges asked Jul 15, 2015 at 12:26 Kevin WhitakerKevin Whitaker 13.5k13 gold badges54 silver badges94 bronze badges
Add a ment  | 

3 Answers 3

Reset to default 5

You'll need the array index, so you can either track it outside the for-of and then use it on the path, or use Array#some instead (or use a boring old for).

Here's tracking the index outside the for-of — I also added an else I think was probably pretty important: :-)

_findInTree = (id, tree, path = "") => {
    let result;
    let index;
    let rv;
    if (tree.id === id) {
        result = tree;
    } else {
        index = 0;
        for (let child of tree.children) {
            if (child.id === id) {
                result = child;
                break;
            }
            rv = this._findInTree(id, child, path + "[" + index + "]");
            if (rv != null) {
                return rv;
            }
            ++index;
        }
    }
    return { result, path };
};

Obviously, adjust the format of path as you see fit. (Doesn't have to be a string, for instance, could be an array.)

Here's the some solution:

_findInTree = (id, tree, path = "") => {
    let result;
    let rv = null;
    if (tree.id === id) {
        result = tree;
    } else {
        tree.children.some((child, index) => {
            if (child.id === id) {
                result = child;
                return true;
            }
            rv = this._findInTree(id, child, path + "[" + index + "]");
            if (rv) {
                return true;
            }
        });
    }
    return rv || { result, path };
};

So T.J. Crowders position ended up having a bug around recording the path, and I ended up tweaking the solution to get the following, which works excellently.

  _findInTree(id, tree) {
    if (tree.id === id) {
      let path = [tree.name];
      return {result: tree, path};
    } else {
      for (let child of tree.children) {
        let tmp = this._findInTree(id, child);
        if (!_.isEmpty(tmp)) {
          tmp.path.unshift(tree.name);
          return tmp;
        }
      }
      return {};
    }
  }

As For me, I need to change Kevin Whitaker code to this one

_findInTree(id, tree) {
    if (tree.id === id) {
      let path = [tree.name];
      return {result: tree, path};
    } else if (tree.children) { //THIS IS THE CHANGES THAT I NEED
      for (let child of tree.children) {
        let tmp = this._findInTree(id, child);
        if (!_.isEmpty(tmp)) {
          tmp.path.unshift(tree.name);
          return tmp;
        }
      }
      return {};
    }
  }

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744196250a4562669.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信