Javascript: 在树中深度查找对象,然后 return 对象及其通过树的路径

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

我有一个看起来像这样的数据结构:

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

我已经编写了一个递归函数来查找该树中的给定对象,但我现在还需要 return 路径 通过树到达对象那是 returned。我正在尝试弄清楚如何修改我的搜索功能来执行此操作。

搜索功能:

_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;
  }

你需要数组索引,所以你可以在 for-of 之外跟踪它,然后在路径上使用它,或者使用 Array#some 代替(或使用无聊的旧 for).

这里是在 for-of 之外跟踪索引 — 我还添加了一个 else 我认为可能非常重要::-)

_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 };
};

显然,根据需要调整 path 的格式。 (不一定是字符串,例如,可以是数组。)

这是 some 解决方案:

_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 };
};

所以T.J。 Crowders 的位置最终在记录路径时出现错误,我最终调整了解决方案以获得以下结果,效果非常好。

  _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 {};
    }
  }

至于我,我需要将 Kevin Whitaker 代码更改为这个代码

_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 {};
    }
  }