[英]How to Convert this Function to Recursive Function
我正在尝试将 JSON 转换为对象数组。
到目前为止,我有这个工作代码,其中参数data
是 JSON。如果存在properties
键,它可以深度嵌套。
因此,在下面的代码中,如果存在properties
键,则循环遍历它并构建一个对象数组。
将其转换为递归 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
};
}
例如,我写了这个递归 function 将 JSON 精确复制到对象数组中,但它不保留嵌套,它只是一个平面数组。 我一直在尝试写一些干净的东西来保持嵌套,但到目前为止没有运气......:(
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 };
}
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"
}
}
}
}
}
}
}
}
}
}
期望的结果:
{
"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",
}
]
}
]
}
]
}
]
}
在普通的 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; }
采用Nina Scholz 的绝妙正确答案并对其进行一些调整,使其包含创建id
属性的key
。 还添加缩进和 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,
};
}
谢谢你们。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.