[英]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.