用于访问嵌套数组中的元素的递归函数和Map

时间:2018-02-07 16:04:19

标签: javascript

场合

  • 我有一个嵌套数组,我有一个要搜索的ID。喜欢" A_02_02_01_03"
  • 数组中的每个元素都有一个名为" children"的元素,即a 阵列
  • 当我在第4层搜索时,我的方法会很长。

示例数组

var tree= [
  {
    "name": "i2",
    "children": [
      {
        "name": "d1",
        "children": [],
        "id": "DW_02_01",
        "beschreibung": "",
        "table": []
      },
      {
        "name": "d2",
        "children": [
          {
            "name": "e1",
            "children": [
              {
                "name": "a1",
                "children": [],
                "id": "A_02_02_01_01",
                "beschreibung": "",
                "table": []
              },
              {
                "name": "a2",
                "children": [],
                "id": "A_02_02_01_02",
                "beschreibung": "",
                "table": []
              },
              {
                "name": "a3",
                "children": [],
                "id": "A_02_02_01_03",
                "beschreibung": "",
                "table": []
              }`enter code here`
            ],
            "id": "E_02_02_01",
            "beschreibung": "",
            "table": []
          },
          {
            "name": "e2",
            "children": [],
            "id": "E_02_02_02",
            "beschreibung": "",
            "table": []
          }
        ],
        "id": "DW_02_02",
        "beschreibung": "",
        "table": []
      },
      {
        "name": "d3",
        "children": [],
        "id": "DW_02_03",
        "beschreibung": "",
        "table": []
      }
    ],
    "id": "IW_02",
    "beschreibung": "",
    "table": []
  },
  {
    "name": "i3",
    "children": [],
    "id": "IW_03",
    "beschreibung": "",
    "table": []
  }
]

构建ID

var daIW = "IW_02";
var daDW = "DW_02_02;
var daE = "E_02_02_01;
var daA = "A_02_02_01_03";

获取所有索引

var iw_index = tree.findIndex(element => element.id == daIW);
var dw_index = tree[iw_index]["children"].findIndex(element => element.id == daDW);
var e_index = tree[iw_index]["children"][dw_index]["children"].findIndex(element => element.id == daE);
var a_index = tree[iw_index]["children"][dw_index]["children"][e_index]["children"].findIndex(element => element.id == daA);

访问我的元素

var elementName = tree[iw_index]["children"][dw_index]["children"][e_index]["children"][a_index].name;

问题

是否有更短的方式来访问最深的元素" A_02_02_01_03"然后搜索每个索引?

3 个答案:

答案 0 :(得分:2)

您可能希望递归首先深入搜索树:

function search(array = [], id){
  for(const node of array){
    if(node.id === id) return node;

    const sub = search(node.children, id);
    if(sub) return sub;
  }
}

所以你可以这样做:

const result = search(tree, "A_02_02_01_03");

如果你想找到多个项目,建立一个存储所有id / node对的哈希表可能会更好,所以查找速度非常快:

function createLookup(array, hash = new Map){
  for(const node of array){
    hash.set(node.id, node);
    createLookup(node.children, hash);
  }
  return hash;
}

所以你可以这样做:

const hash = createLookup(tree);
const result = hash.get("A_02_02_01_03");

答案 1 :(得分:1)

我假设由于某种原因你不能只用id == "A_02_02_01_03"搜索条目。例如,由于某种原因您需要其他ID。

现在您已确认叶节点ID是唯一的,Jonas w's answer仅使用叶节点ID(例如,"A_02_02_01_03")将起作用。如果您有其他可用的ID,那么可以通过避免访问您不需要访问的节点来加快流程,但是您必须拥有一个非常重要的树。

如果确实重要,这个答案仍然适用:

我可能会使用递归函数:

function find(node, ids, index = 0) {
    const id = ids[index];
    const entry = node.find(e => e.id == id);
    if (!entry) {
        return null;
    }
    ++index;
    return index < ids.length ? find(entry.children, ids, index) : entry;
}

然后像这样调用它:

const result = find(tree, [daIW, daDW, daE, daA]);

假设您希望输入结果。

直播示例:

var tree= [
  {
    "name": "i2",
    "children": [
      {
        "name": "d1",
        "children": [],
        "id": "DW_02_01",
        "beschreibung": "",
        "table": []
      },
      {
        "name": "d2",
        "children": [
          {
            "name": "e1",
            "children": [
              {
                "name": "a1",
                "children": [],
                "id": "A_02_02_01_01",
                "beschreibung": "",
                "table": []
              },
              {
                "name": "a2",
                "children": [],
                "id": "A_02_02_01_02",
                "beschreibung": "",
                "table": []
              },
              {
                "name": "a3",
                "children": [],
                "id": "A_02_02_01_03",
                "beschreibung": "",
                "table": []
              }
            ],
            "id": "E_02_02_01",
            "beschreibung": "",
            "table": []
          },
          {
            "name": "e2",
            "children": [],
            "id": "E_02_02_02",
            "beschreibung": "",
            "table": []
          }
        ],
        "id": "DW_02_02",
        "beschreibung": "",
        "table": []
      },
      {
        "name": "d3",
        "children": [],
        "id": "DW_02_03",
        "beschreibung": "",
        "table": []
      }
    ],
    "id": "IW_02",
    "beschreibung": "",
    "table": []
  },
  {
    "name": "i3",
    "children": [],
    "id": "IW_03",
    "beschreibung": "",
    "table": []
  }
];

var daIW = "IW_02";
var daDW = "DW_02_02";
var daE = "E_02_02_01";
var daA = "A_02_02_01_03";

function find(node, ids, index = 0) {
    const id = ids[index];
    const entry = node.find(e => e.id == id);
    if (!entry) {
        return null;
    }
    ++index;
    return index < ids.length ? find(entry.children, ids, index) : entry;
}

console.log(find(tree, [daIW, daDW, daE, daA]));

答案 2 :(得分:0)

尝试以下递归功能

//函数

  function getelement(vtree, id) {
      vtree.forEach(function(treeitem) {
        if(treeitem["id"] === id) {
            console.log(treeitem);
        }
        else if(treeitem["children"].length){
            getelement(treeitem["children"], id);
        }
    });
  };

//呼叫者

getelement(tree,"A_02_02_01_03");