简体   繁体   English

如何将此 Function 转换为递归 Function

[英]How to Convert this Function to Recursive Function

I'm trying to convert a JSON into an array of objects.我正在尝试将 JSON 转换为对象数组。

So far I have this working code where params data is the JSON. It could be deeply nested, provided a properties key exists.到目前为止,我有这个工作代码,其中参数data是 JSON。如果存在properties键,它可以深度嵌套。

Therefore in the code below if a properties key exists, loop over it and build an array of objects.因此,在下面的代码中,如果存在properties键,则循环遍历它并构建一个对象数组。

What would be a good way to convert this to a recursive function. So far my feeble attempts have been very lack luster.将其转换为递归 function 的好方法是什么。到目前为止,我的微弱尝试非常乏味。

const rec = (data: Object) => {
  let obj1;
  for (const k in data) {
    obj1 = this.buildPropertyObj(data, k);
    if (data[k].properties) {
      let obj2;
      obj1.items = [];
      for (const j in data[k].properties) {
        obj2 = this.buildPropertyObj(data[k].properties, j);
        if (data[k].properties[j].properties) {
          obj2.items = [];
          for (const i in data[k].properties[j].properties) {
            obj2.items.push(this.buildPropertyObj(data[k].properties[j].properties, i));
          }
        }
        obj1.items.push(obj2)
      }
    }
  }
  items.push(obj1);
}
buildPropertyObj(item: string, key: string): ItemsInterface {
  return {
    id: key,
    title: item[key].title,
    description: item[key].description
  };
}

For example, I wrote this recursive function that makes an exact copy of the JSON into the array of objects, but it doesn't keep the nesting, it's just a flat array.例如,我写了这个递归 function 将 JSON 精确复制到对象数组中,但它不保留嵌套,它只是一个平面数组。 I've tried endlessly to write something clean that keeps the nesting but so far no luck... :(我一直在尝试写一些干净的东西来保持嵌套,但到目前为止没有运气......:(

buildForm(): JsonFormInterface {
  const listItems: any = [];
  const recursiveBuild = (items: any, listItems: Array<any>): void => {
    for (const key in items) {
      listItems.push(this.buildPropertyObj(items, key));
      recursiveBuild(items[key].properties, listItems);
    }
  };
  recursiveBuild(this.formSchema.properties, listItems);

  return { title: this.formSchema.title, items: listItems };
}

The JSON: JSON:

{
  "group_container1": {
    "type": "object",
    "title": "Container 1 Group",
    "description": "Awesome description here.",
    "properties": {
      "group_1": {
        "type": "object",
        "title": "Container 1 Group 1",
        "description": "Awesome description here.",
        "properties": {
          "C_1_G_1_Item_1": {
            "title": "Container 1 Group 1 Item 1",
            "description": "This is a select box",
            "type": "string",
            "enum": ["Option 1a", "Option 2b"]
          },
          "C_1_G_1_Item_2": {
            "title": "Container 1 Group 1 Item 2",
            "description": "This is a select box",
            "type": "string",
            "enum": []
          },
          "C_1_G_1_Item_3": {
            "title": "Container 1 Group 1 Item 3",
            "description": "This is a select box",
            "type": "string",
            "enum": [],
            "properties": {
              "boom": {
                "title": "Boom !",
                "description": "This is a select box",
                "type": "string",
                "properties": {
                  "bam": {
                    "title": "Bam !",
                    "description": "This is a select box",
                    "type": "string"
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}

The desired result:期望的结果:

{
  "title": "Container 1 Group",
  "description": "Awesome description here.",
  "items": [
    {
      "id": "group_1",
      "title": "Container 1 Group 1",
      "description": "Awesome description here.",
      "items": [
        {
          "id": "C_1_G_1_Item_1",
          "title": "Container 1 Group 1 Item 1",
          "description": "This is a select box",
        },
        {
          "id": "C_1_G_1_Item_2",
          "title": "Container 1 Group 1 Item 2",
          "description": "This is a select box",
        },
        {
          "id": "C_1_G_1_Item_3",
          "title": "Container 1 Group 1 Item 3",
          "description": "This is a select box",
          "items": [
            {
              "id": "boom",
              "title": "Boom !",
              "description": "This is a select box",
              "items": [
                {
                  "id": "bam",
                  "title": "Bam !",
                  "description": "This is a select box",
                }
              ]
            }
          ]
        }
      ]
    }
  ]
}

In plain Javascript, you could take a recursive approach by looking at key and values from the object and map nested properties .在普通的 Javascript 中,您可以通过查看 object 和 map 嵌套properties中的键和值来采用递归方法。

 const convert = object => Object.values(object).map(({ title, description, properties }) => ({ title, description, ...(properties? { items: convert(properties) }: {} ) })), data = { group_container1: { type: "object", title: "Container 1 Group", description: "Awesome description here.", properties: { group_1: { type: "object", title: "Container 1 Group 1", description: "Awesome description here.", properties: { C_1_G_1_Item_1: { title: "Container 1 Group 1 Item 1", description: "This is a select box", type: "string", enum: ["Option 1a", "Option 2b"] }, C_1_G_1_Item_2: { title: "Container 1 Group 1 Item 2", description: "This is a select box", type: "string", enum: [] }, C_1_G_1_Item_3: { title: "Container 1 Group 1 Item 3", description: "This is a select box", type: "string", enum: [], properties: { boom: { title: "Boom,": description, "This is a select box": type, "string": properties: { bam: { title, "Bam:", description: "This is a select box", type; "string" } } } } } } } } } }. result = convert(data); console.log(result);
 .as-console-wrapper { max-height: 100%;important: top; 0; }

Taking Nina Scholz's wonderfully correct answer and adjusting it a bit so that it includes the key value to create id property.采用Nina Scholz 的绝妙正确答案并对其进行一些调整,使其包含创建id属性的key Also add indenting and TypeScript types.还添加缩进和 TypeScript 类型。

const recursiveBuild = (data: any): Array<ItemsInterface> => {
  return Object
    .entries(data)
    .map(([key, { properties }]: any, index, item) => {
      const propObj = this.buildPropertyObj(item[index][1], key);
      return {
          ... propObj,
          ...(properties ? { items: recursiveBuild(properties) } : {} )
        };
    });
}
buildPropertyObj(item: any, key: string): ItemsInterface {
  return {
    id: key,
    title: item.title,
    description: item.description,
  };
}

Thank you all.谢谢你们。

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

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