使用lodash在嵌套的有效负载中查找具有给定id的节点

时间:2018-03-18 16:21:04

标签: arrays json typescript lodash

我有以下嵌套的JSON有效负载,我想要迭代,并使用id找到匹配的lodash值(我显然还是要抓住它与lodash)。下面是有效载荷的示例,以及我使用的功能 - 这看起来有点冗长。有没有更简单的方法来完成我需要的东西?

JSON Payload:

{
  "_expanded": true,
  "_canDrop": false,
  "_id": "-1",
  "_name": "root",
  "_children": [
    {
      "_expanded": true,
      "_canDrop": false,
      "_id": "1",
      "_name": "Child 1",
      "_children": [
        {
          "_expanded": true,
          "_canDrop": false,
          "_id": "1-1",
          "_name": "Child 1-1",
          "_children": [
            {
              "_expanded": false,
              "_canDrop": false,
              "_id": "1-1-1",
              "_name": "Child 1-1-1",
              "_children": []
            }
          ]
        },
        {
          "_expanded": false,
          "_canDrop": false,
          "_id": "1-2",
          "_name": "Child 1-2",
          "_children": []
        },
        {
          "_expanded": false,
          "_canDrop": false,
          "_id": "1-3",
          "_name": "Child 1-3",
          "_children": []
        }
      ]
    },
    {
      "_expanded": true,
      "_canDrop": false,
      "_id": "2",
      "_name": "Child 2",
      "_children": [
        {
          "_expanded": false,
          "_canDrop": false,
          "_id": "2-2",
          "_name": "Child 2-2",
          "_children": []
        }
      ]
    }
  ]
}

功能:

  public findNode = (id: any): TreeNode => {
    let result = null;

    _.find(this._children, function(child) {
      if (child._id === id) {
        result = child;
      } else {
        if (child._children.length > 0) {
          _.find(child._children, function(item) {
            result = this.findNode(item._id);
          })
        }
      }
    });
    return result;
  }

1 个答案:

答案 0 :(得分:0)

Lodash没有与深度搜索相关的任何内容,因此您必须自己实现算法的树方面。

您尝试使用的Additionaly _.find用于查找与谓词匹配的元素,但不允许您更改结果。它最多只能找到他或他的一个孩子有一个根节点_id

因此,必须手动编写此算法:

function findNode(id: any, node: any) {
    if (node._id === id) {
        return node;
    }
    for (const child of node._children) {
        const r = findNode(id, child);
        if (r !== undefined) {
            return r;
        }
    }
    return undefined;
}

如果您真的坚持要更多功能,可以使用reduce来替换children上的循环:

return _.reduce(node._children, (result, child) => {
    if (result !== undefined) {
        return result;
    }
    return findNode(id, child);
}, undefined)

这基本上是对孩子进行迭代并检查每个孩子,除非已找到某些东西