简体   繁体   English

TypeScript 中的递归 Function - 父数组

[英]Recursive Function in TypeScript - Parents Array

I want to create a recursive function that receive a List of objects that contains the id and parent_id.我想创建一个递归 function 接收包含 id 和 parent_id 的对象列表。 If the parent of an element is in the list I want to remove it and add it to the parent.如果元素的父元素在列表中,我想将其删除并将其添加到父元素。

Convert this:转换这个:

{
  "id": 180,
  "children": [],
  "parent_id": 195,
  "name": "Object 180"
},
{
  "id": 193,
  "children": [],
  "parent_id": 180,
  "name": "Object 193"
},
{
  "id": 194,
  "children": [],
  "parent_id": 180,
  "name": "Object 194"
}
{
  "id": 199,
  "children": [],
  "parent_id": 187,
  "name": "Object 199"
}
{
  "id": 304,
  "children": [],
  "parent_id": 193,
  "name": "Object 304"
}

To this:对此:

{
  "id": 180,
  "children": [
    {
      "id": 193,
      "children": [
        {
          "id": 304,
          "children": [],
          "parent_id": 193,
          "name": "Object 304"
         }
      ],
      "parent_id": 180,
      "name": "Object 193"
    },
    {
      "id": 194,
      "children": [],
      "parent_id": 180,
      "name": "Object 194"
    }
  ],
  "parent_id": 195,
  "name": "Object 180"
},
{
  "id": 199,
  "children": [],
  "parent_id": 187,
  "name": "Object 199"
}

Sometimes the parent_id is null, and there is no limit of levels of the parents.有时parent_id是null,并且没有父母等级限制。

You don't need a recursive function.不需要递归 function。 Just track items you've already seen and if parent exists in it add to parent.children or add a new root node.只需跟踪您已经看过的项目,如果其中存在父项,则添加到parent.children或添加新的根节点。

An example complete solution is attached.附上一个完整的示例解决方案。

Complete code完整代码

type Item = {
    id: number,
    children: Item[],
    parent_id: number,
    name: string,
}

const items: Item[] = [
    {
        "id": 180,
        "children": [],
        "parent_id": 195,
        "name": "Object 180"
    },
    {
        "id": 193,
        "children": [],
        "parent_id": 180,
        "name": "Object 193"
    },
    {
        "id": 194,
        "children": [],
        "parent_id": 180,
        "name": "Object 194"
    },
    {
        "id": 199,
        "children": [],
        "parent_id": 187,
        "name": "Object 199"
    },
    {
        "id": 304,
        "children": [],
        "parent_id": 193,
        "name": "Object 304"
    }
];


function nest(items:Item[]): Item[] {
  const output: Item[] = [];
  const idToItem = new Map<number,Item>();
  for (let item of items) {
      // Either add to parent. Or create a new root level node
      if (idToItem.has(item.parent_id)) {
          idToItem.get(item.parent_id)!.children.push(item);
      } else {
          idToItem.set(item.id, item);
          output.push(item);
      }
  }
  return output;
}

console.log(nest(items));

Since basarat's answer does not account for items nested more than one level.由于 basarat 的答案没有考虑嵌套超过一层的项目。

Here a solution that creates an output with arbitrary nesting-depth:这是一个创建具有任意嵌套深度的 output 的解决方案:

 const listToTree = (input) => { const map = new Map(input.map((item) => [item.id, item])); const output = []; for (const item of input) { if (map.has(item.parent_id)) { map.get(item.parent_id).children.push(map.get(item.id)); } else { output.push(map.get(item.id)); } } return output; }; const input = [ { "id": 180, "children": [], "parent_id": 195, "name": "Object 180" }, { "id": 193, "children": [], "parent_id": 180, "name": "Object 193" }, { "id": 194, "children": [], "parent_id": 180, "name": "Object 194" }, { "id": 199, "children": [], "parent_id": 187, "name": "Object 199" }, { "id": 304, "children": [], "parent_id": 193, "name": "Object 304" }, { "id": 305, "children": [], "parent_id": 194, "name": "Object 304" } ]; const output = listToTree(input); console.log(output);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM