Is there a way to union multiple nodes based on ID

2019-09-16 15:16发布

问题:

I have 3 different object / node as below, and I am trying to form the finalObj / node which is the union (unique tree list) of the 3 nodes..

Is there a method in tree view with which I can union 3 objects (nodes) based on text or id ?

First node: 

 [ { text: "TreeRoot", items: [
                                { text: "Subgroup1" },
                                { text: "Subgroup2" }   
                            ]}]

Second Node:
                 [ { text: "TreeRoot", items: [
                            { text: "Subgroup3" }   
                        ]}]


Third node:
                 [{ text: "Subgroup3",
                        items: [ {
                                text: "subgroup5",
                                items: [ {
                                        text: "subgroup6",
                                        items: [ {
                                                text: "subgroup7",
                                                items: [ {
                                                        text: "subgroup8"
                                                    }]
                                            }] }] 
                            }]}]



Final expected node (after merging):

                var finalObj= [ { text: "TreeRoot", items: [
                            { text: "Subgroup1" },
                            { text: "Subgroup2" },
                            { text: "Subgroup3",
                                items: [ {
                                        text: "subgroup5",
                                        items: [ {
                                                text: "subgroup6",
                                                items: [ {
                                                        text: "subgroup7",
                                                        items: [ {
                                                                text: "subgroup8"
                                                            }]
                                                    }] }] 
                                    }]}]}]

EDIT:

The below solution doesnt work for other type of nodes..

For EX:

   var node1 = [
                    { text   : "TreeRoot",
                        id:0,
                        items: [
                            { text: "Subgroup1",id:1 },
                            { text: "Subgroup2", id:2}
                        ]
                    }
                ];

            var node2 = [
                {
                    text : "TreeRoot",
                    id:0,
                    items: [
                        { text: "Subgroup3" ,
                        id:3}
                    ]
                }
            ];


            var node3 = [
                {
                    text : "TreeRoot",
                     id:0,
                    items: [
                        {
                            text : "Subgroup2",
                            id:2,
                            items: [
                                {
                                    text : "subgroup6",
                                    id:6,
                                    items: [
                                        {
                                            text : "subgroup7",
                                            id:7,
                                            items: [
                                                {
                                                    text: "subgroup8",
                                                    id:8
                                                }
                                            ]
                                        }
                                    ]
                                }
                            ]
                        }
                    ]
                }
            ];

For above example I should see just tree root initially. When expanded I should see just subgroup1,2,3... and when subgroup2 is expanded I should be able to see subgroup6,7,8.

I need unique parent and child nodes.. If I use the above structure, I get 2 child node named- Subgroup3

回答1:

Although you tag it as Kendo-UI it is actually a programming problem since there is no KendoUI interface for solving (I know that you want to use it for merging treeview nodes) it but it is not very hard solving it using recursion.

This are basically your three nodes:

var node1 = [
    { text   : "TreeRoot",
        items: [
            { text: "Subgroup1" },
            { text: "Subgroup2" }
        ]
    }
];

var node2 = [
    {
        text : "TreeRoot",
        items: [
            { text: "Subgroup3" }
        ]
    }
];


var node3 = [
    {
        text : "Subgroup3",
        items: [
            {
                text : "subgroup5",
                items: [
                    {
                        text : "subgroup6",
                        items: [
                            {
                                text : "subgroup7",
                                items: [
                                    {
                                        text: "subgroup8"
                                    }
                                ]
                            }
                        ]
                    }
                ]
            }
        ]
    }
];

You can merge it using the following function:

function merge(node1, node2) {
    if (node2 !== null) {
        if (node1.text === node2.text) {
            node1.items = node1.items || [];
            $.each(node2.items, function (idx2, elem2) {
                var found = false;
                // Check that elem does not exist on node1
                $.each(node1.items, function (idx1, elem1) {
                    if (!found && elem1.text === elem2.text) {
                        found = true;
                        merge(elem1, elem2);
                    }
                });
                if (!found) {
                    node1.items.push(elem2);
                }
            });
        } else {
            if (node1.items) {
                $.each(node1.items, function (idx, item) {
                    merge(item, node2);
                });
            }
        }
    }
}

That merges two nodes in the first one.

And you should invoke it like this:

merge(node1[0], node2[0]);
merge(node1[0], node3[0]);

for your scenario.

NOTE: I'm assuming that you only have one element on each of the nodes (i.e. node0, node1 and node2 are arrays but they only have one element)

See it running here