递归遍历树形结构,查找目标元素

发布时间 2023-11-15 16:51:12作者: shellon

树形结构的数据,即源数据:

const origin =
{
  "id": "40953897304457339",
  "name": "一级单位",
  "children": [
    {
      "id": "52979376890839070",
      "name": "二级单位1",
      "children": null
    },
    {
      "id": "42225681513316475",
      "name": "二级单位2",
      "children": null
    },
    {
      "id": "41822511372960975",
      "name": "二级单位3",
      "children": null
    },
    {
      "id": "40924378111672443",
      "name": "二级单位4",
      "children": [
        {
          "id": "40927544324653179",
          "name": "三级单位41",
          "children": null
        },
        {
          "id": "40927281190797435",
          "name": "三级单位42",
          "children": [
            {
              "id": "40920270965309563",
              "name": "四级单位421",
              "children": [
                {
                  "id": "40922872926961787",
                  "name": "五级单位4211",
                  "children": null
                }
              ]
            }
          ]
        }
      ]
    }
  ]
}

要查找的元素,已知id,即目标数据id:40922872926961787

实现代码:

1. 仅返回匹配到的元素;

// IMenuItem 仅是对数据结构的定义,可自行处理,或者使用any代替
const findCompanyViaId = (id: string, list: IMenuItem[]): any => {
   // 防止更改源数据
  const copayList: IMenuItem[] = JSON.parse(JSON.stringify(list));
  let company: IMenuItem | undefined = undefined;
  for (let i = 0; i < copayList.length; i++) {
    const item = copayList[i];
    if (item.id === id) {
      return item;
    }
    if (item.children && item.children.length>0){
      company = findCompanyViaId(id, item.children);
      return company;
    }
  }
};


findCompanyViaId(40922872926961787, origin);
// 返回结果
{
  "id": "40922872926961787",
  "name": "五级单位4211",
  "children": null
}

2.  返回匹配到的元素及其路径上的所有元素;

// IMenuItem 仅是对数据结构的定义,可自行处理,或者使用any代替
const findCompanyTreeViaId = (id: string, list: IMenuItem[]): any => {
   // 防止更改源数据
  const copayList: IMenuItem[] = JSON.parse(JSON.stringify(list));
  const companyTree: IMenuItem[] = [];
  for (let i = 0; i < copayList.length; i++) {
    const item = copayList[i];
    if (item.id === id) {
      return item;
    } else if (item.children) {
      const company = findCompanyTreeIdViaId(id, item.children);
      item.children = company;
      return item;
    }
  }
};


findCompanyTreeViaId(40922872926961787, origin);
// 返回结果
{
  "id": "40953897304457339",
  "name": "一级单位",
  "children": [
    {
      "id": "40924378111672443",
      "name": "二级单位4",
      "children": [
        {
          "id": "40927281190797435",
          "name": "三级单位42",
          "children": [
            {
              "id": "40920270965309563",
              "name": "四级单位421",
              "children": [
                {
                  "id": "40922872926961787",
                  "name": "五级单位4211",
                  "children": null
                }
              ]
            }
          ]
        }
      ]
    }
  ]
}

3. 在2基础上的变形, 返回匹配到的元素及其路径上的所有元素的id;

// IMenuItem 仅是对数据结构的定义,可自行处理,或者使用any代替
const findCompanyTreeIdsViaId = (id: string, list: IMenuItem[]): any => {
   // 防止更改源数据
  const copayList: IMenuItem[] = JSON.parse(JSON.stringify(list));
  const companyTreeIds: string[] = [];
  for (let i = 0; i < copayList.length; i++) {
    const item = copayList[i];
    if (item.id === id) {
      return [item.id];
    } else if (item.children) {
      const companyId = findCompanyTreeIdViaId(id, item.children);
      companyId && companyTreeIds.push(item.id, companyId);
      return companyTreeIds;
    }
  }
};


findCompanyTreeIdsViaId(40922872926961787, origin);
// 返回结果
["40953897304457339",["40924378111672443",["40927281190797435",["40920270965309563",["40922872926961787"]]]]]
// 可以通过Array.flat()方法将多维数组扁平化,具体用法参考 https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/flat
// 将上述结果赋值给arr
arr.flat(Infinity);
// 结果
["40953897304457339","40924378111672443","40927281190797435","40920270965309563","40922872926961787"]