【问题标题】:How Iterate deeply nested object array to create new nested node for data tree如何迭代深度嵌套的对象数组为数据树创建新的嵌套节点
【发布时间】:2021-09-29 09:43:38
【问题描述】:

我正在尝试从现有的深度嵌套对象数组创建新的嵌套树对象数组,以构建我想要的树节点 ID、名称及其嵌套子对象(如果有)。

 const treeData = [{
            "jssType": "fieldset",
            "jssSelectLabel": "Fieldset (with legend)",
            "jssSelectGroup": "jssItem",
            "jsName": "fieldset-715",
            "jssLabel": "Legend",
            "jssIcon": "typcn typcn-folder",
            "expanded": true,
            "children": [{
                    "jssType": "list-ol",
                    "jssSelectLabel": "List - ol",
                    "jssSelectGroup": "jssItem",
                    "jsName": "list-ol-147",
                    "jssLabel": "",
                    "jssIcon": "dashicons dashicons-editor-ol",
                    "noChildren": false,
                    "expanded": true,
                    "children": [{
                            "jssType": "list-li",
                            "jssSelectLabel": "List Item - li",
                            "jssSelectGroup": "jssItem",
                            "jsName": "list-li-752",
                            "jssLabel": "",
                            "jssIcon": "dashicons dashicons-editor-ul",
                            "noChildren": false,
                            "expanded": true,
                            "children": [{
                                "jssType": "text",
                                "jssSelectLabel": "Text (short text)",
                                "jssSelectGroup": "jsTag",
                                "jsName": "text-422",
                                "jssLabel": "Your Name (required)",
                                "jsRequired": true,
                                "jsTagOptions": [{
                                        "jsOption": "",
                                        "optionLabel": "Default value",
                                        "optionType": "input"
                                    },
                                    {
                                        "jsOption": "placeholder",
                                        "isChecked": false,
                                        "optionLabel": "Use this text as the placeholder of the field",
                                        "optionType": "checkbox"
                                    },
                                    {
                                        "jsOption": "akismet_author_email",
                                        "isChecked": false,
                                        "optionLabel": "Akismet - this field requires author's email address",
                                        "optionType": "checkbox"
                                    }
                                ],
                                "jsValues": "",
                                "jsPlaceholder": false,
                                "jsAkismetAuthor": false,
                                "jsIdAttribute": "",
                                "jsClassAttribute": "",
                                "jssIcon": "typcn typcn-sort-alphabetically",
                                "noChildren": true
                            }]
                        },
                        {
                            "jssType": "list-li",
                            "jssSelectLabel": "List Item - li",
                            "jssSelectGroup": "jssItem",
                            "jsName": "list-li-538",
                            "jssLabel": "",
                            "jssIcon": "dashicons dashicons-editor-ul",
                            "noChildren": false,
                            "expanded": true,
                            "children": [{
                                "jssType": "email",
                                "jssSelectLabel": "Email",
                                "jssSelectGroup": "jsTag",
                                "jsName": "email-842",
                                "jssLabel": "Email Address (required)",
                                "jsRequired": true,
                                "jsTagOptions": [{
                                        "jsOption": "",
                                        "optionLabel": "Default value",
                                        "optionType": "input"
                                    },
                                    {
                                        "jsOption": "placeholder",
                                        "isChecked": false,
                                        "optionLabel": "Use this text as the placeholder of the field",
                                        "optionType": "checkbox"
                                    },
                                    {
                                        "jsOption": "akismet_author_email",
                                        "isChecked": false,
                                        "optionLabel": "Akismet - this field requires author's email address",
                                        "optionType": "checkbox"
                                    }
                                ],
                                "jsValues": "",
                                "jsPlaceholder": false,
                                "jsAkismetAuthorEmail": false,
                                "jsIdAttribute": "",
                                "jsClassAttribute": "",
                                "jssIcon": "typcn typcn-mail",
                                "noChildren": true
                            }]
                        },
                        {
                            "jssType": "list-li",
                            "jssSelectLabel": "List Item - li",
                            "jssSelectGroup": "jssItem",
                            "jsName": "list-li-855",
                            "jssLabel": "",
                            "jssIcon": "dashicons dashicons-editor-ul",
                            "noChildren": false,
                            "expanded": true,
                            "children": [{
                                "jssType": "textarea",
                                "jssSelectLabel": "Textarea (long text)",
                                "jssSelectGroup": "jsTag",
                                "jsName": "textarea-217",
                                "jssLabel": "Your Message",
                                "jsRequired": false,
                                "jsTagOptions": [{
                                        "jsOption": "",
                                        "optionLabel": "Default value",
                                        "optionType": "input"
                                    },
                                    {
                                        "jsOption": "placeholder",
                                        "isChecked": false,
                                        "optionLabel": "Use this text as the placeholder of the field",
                                        "optionType": "checkbox"
                                    }
                                ],
                                "jsValues": "",
                                "jsPlaceholder": false,
                                "jsIdAttribute": "",
                                "jsClassAttribute": "",
                                "jssIcon": "typcn typcn-document-text",
                                "noChildren": true
                            }]
                        }
                    ]
                },
                {
                    "jssType": "paragraph",
                    "jssSelectLabel": "Paragraph - p",
                    "jssSelectGroup": "jssItem",
                    "jsName": "paragraph-993",
                    "jssContent": "* Required",
                    "jssIcon": "dashicons dashicons-editor-paragraph",
                    "noChildren": true
                }
            ]
            
        },
        {
            "jssType": "submit",
            "jssSelectLabel": "Submit",
            "jssSelectGroup": "jsTag",
            "jsName": "submit-704",
            "jssLabel": "Send",
            "jsValues": "",
            "jsRequired": false,
            "jsIdAttribute": "",
            "jsClassAttribute": "",
            "jssIcon": "typcn typcn-mail",
            "noChildren": true
        },
        
    ];

My expected data will be in format like below model:

    export class TreeNode {
      id: number;
      label: string;
      level: number;
      expandable: boolean;
      children: TreeNode[];
      sequence?: string; 
      isParentNode?: boolean;
    }

我可以使用多个循环来实现这一点,但在这种情况下很多代码是重复的,所以我正在寻找一些递归函数。因此,使用最少的 cade,我将能够检索整个数组并从中准备新的对象数组。 任何人都可以帮助我实现这一目标。提前谢谢你。

注意:使用这个新创建的数据,我想在 ui 上显示材质嵌套树。

【问题讨论】:

  • 你能给出你想要的示例格式吗
  • 当然@JagadishLenka,我正在寻找以下数据格式:let treeData =[{ id: 1 label: ParentOne, level: 0, expandable: true, children: [{ id: 1 label: childOne ,级别:1,可扩展:true,子项:[{ id:1 标签:nestedChild1,级别:2,可扩展:true },{ id:1 标签:nestedChild2,级别:2,可扩展:true}] }] }] ;它是我树的单个节点。我尝试过递归,但它给了我最大堆栈调用错误并且应用程序卡住了

标签: javascript angular angular-material tree


【解决方案1】:

听起来应该很容易通过递归实现

function treeDataToTree(treeData: any[], level = 0): TreeNode[] {
   return treeData.map(item => treeItemToTree(item, level));
}

function treeItemToTree(treeDataItem: any, level = 0): TreeNode {
   const treeNode = new TreeNode();
   treeNode.id=treeDataItem.id;
   // other fields that you need
   if(treeDataItem.children) treeNode.children = treeDataToTree(treeDataItem.children, level + 1);
   return treeNode;
}

【讨论】:

    【解决方案2】:

    考虑index as idjssSelectLabel as label,可以相应替换。通过Boolean(children.length)找出isParentNode

    Angular demo

    const treeData=[{"jssType":"fieldset","jssSelectLabel":"Fieldset (with legend)","jssSelectGroup":"jssItem","jsName":"fieldset-715","jssLabel":"Legend","jssIcon":"typcn typcn-folder","expanded":true,"children":[{"jssType":"list-ol","jssSelectLabel":"List - ol","jssSelectGroup":"jssItem","jsName":"list-ol-147","jssLabel":"","jssIcon":"dashicons dashicons-editor-ol","noChildren":false,"expanded":true,"children":[{"jssType":"list-li","jssSelectLabel":"List Item - li","jssSelectGroup":"jssItem","jsName":"list-li-752","jssLabel":"","jssIcon":"dashicons dashicons-editor-ul","noChildren":false,"expanded":true,"children":[{"jssType":"text","jssSelectLabel":"Text (short text)","jssSelectGroup":"jsTag","jsName":"text-422","jssLabel":"Your Name (required)","jsRequired":true,"jsTagOptions":[{"jsOption":"","optionLabel":"Default value","optionType":"input"},{"jsOption":"placeholder","isChecked":false,"optionLabel":"Use this text as the placeholder of the field","optionType":"checkbox"},{"jsOption":"akismet_author_email","isChecked":false,"optionLabel":"Akismet - this field requires author's email address","optionType":"checkbox"}],"jsValues":"","jsPlaceholder":false,"jsAkismetAuthor":false,"jsIdAttribute":"","jsClassAttribute":"","jssIcon":"typcn typcn-sort-alphabetically","noChildren":true}]},{"jssType":"list-li","jssSelectLabel":"List Item - li","jssSelectGroup":"jssItem","jsName":"list-li-538","jssLabel":"","jssIcon":"dashicons dashicons-editor-ul","noChildren":false,"expanded":true,"children":[{"jssType":"email","jssSelectLabel":"Email","jssSelectGroup":"jsTag","jsName":"email-842","jssLabel":"Email Address (required)","jsRequired":true,"jsTagOptions":[{"jsOption":"","optionLabel":"Default value","optionType":"input"},{"jsOption":"placeholder","isChecked":false,"optionLabel":"Use this text as the placeholder of the field","optionType":"checkbox"},{"jsOption":"akismet_author_email","isChecked":false,"optionLabel":"Akismet - this field requires author's email address","optionType":"checkbox"}],"jsValues":"","jsPlaceholder":false,"jsAkismetAuthorEmail":false,"jsIdAttribute":"","jsClassAttribute":"","jssIcon":"typcn typcn-mail","noChildren":true}]},{"jssType":"list-li","jssSelectLabel":"List Item - li","jssSelectGroup":"jssItem","jsName":"list-li-855","jssLabel":"","jssIcon":"dashicons dashicons-editor-ul","noChildren":false,"expanded":true,"children":[{"jssType":"textarea","jssSelectLabel":"Textarea (long text)","jssSelectGroup":"jsTag","jsName":"textarea-217","jssLabel":"Your Message","jsRequired":false,"jsTagOptions":[{"jsOption":"","optionLabel":"Default value","optionType":"input"},{"jsOption":"placeholder","isChecked":false,"optionLabel":"Use this text as the placeholder of the field","optionType":"checkbox"}],"jsValues":"","jsPlaceholder":false,"jsIdAttribute":"","jsClassAttribute":"","jssIcon":"typcn typcn-document-text","noChildren":true}]}]},{"jssType":"paragraph","jssSelectLabel":"Paragraph - p","jssSelectGroup":"jssItem","jsName":"paragraph-993","jssContent":"* Required","jssIcon":"dashicons dashicons-editor-paragraph","noChildren":true}]},{"jssType":"submit","jssSelectLabel":"Submit","jssSelectGroup":"jsTag","jsName":"submit-704","jssLabel":"Send","jsValues":"","jsRequired":false,"jsIdAttribute":"","jsClassAttribute":"","jssIcon":"typcn typcn-mail","noChildren":true},];
    
    function nodeMapper(obj, id, level=0){
        const { expanded:expandable, jssSelectLabel:label} =obj;
        let children = [];
        const resp = { id,  label, expandable, level };
    
        // if has childern then make recersive call to nodeMapper function for each childern
        if(obj.children){
            children = obj.children.map((o,i )=> nodeMapper(o,i, level+1));
        }
        return { ...resp, children, isParentNode: Boolean(children.length) };
    }
    
    const result = treeData.map((o, i) => nodeMapper(o, i));
    
    console.log(result);

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-07-19
      • 2020-03-16
      • 2017-06-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-01-29
      相关资源
      最近更新 更多