1

我有 3 个不同的对象(obj1,2,3),如下所示,我正在尝试形成 finalObj,它是 3 个对象的并集(唯一树列表)..

我不确定实现这一目标的最佳方法是什么。

编辑:文本是这里的关键。如果已经存在具有相同文本的父节点,我们只需忽略并移动到其子节点并检查该子节点是否存在,否则将该子节点附加到现有父节点等等......

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

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

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



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

3 回答 3

3
var table = {}; // items by id
function recurse(items) {
    for (var i=0; i<items.length; i++) {
        var item = items[i],
            id = item.text;
        if (id in table) 
            table[id].items = (table[id].items && item.items)
              ? table[id].items.concat(item.items) // merge
              : table[id].items || item.items;
        else
            table[id] = item;
        if (item.items)
            recurse(item.items);
    }
}
recurse(obj1), recurse(obj2), recurse(obj3);

// assuming there are no cycles and only one parent per node in the graph
for (var text in table) (function recurse(text) {
    var items = table[text].items;
    if (!items) continue;
    for (var i=0; i<items.length; i++) {
        var id = items[i].text;
        if (id in table) {
            items[i] = table[id];
            recurse(id);
            delete table[id];
        }
    }
})(text);

// now, table consists only of the root keys (should be only one):
for (var id in table)
    var finalObj = table[id];
于 2013-01-08T00:38:44.403 回答
2

这里的诀窍是以利用 javascript 对象的自然特征并促进合并的方式构造对象。

obj1,obj2和中的所有数组obj3都是多余的,因为它们每个都包含不超过一项。

与其使用属性text和构造对象items,不如使用文本作为键,将项目作为其属性,从而提供更紧凑的数据结构。

var obj1 = {
    "Subgroup1": null,
    "Subgroup2": null
};
var obj2 = {
    "Subgroup3": null
};
var obj3 = {
    "Subgroup3": {
        "subgroup5": {
            "subgroup6": {
                "subgroup7": {
                    "subgroup8": null
                }
            }
        }
    }
};

现在您可以使用 jQuery 的强大功能了$.extend()

var finalObj = $.extend(true, {}, obj1, obj2, obj3);

这使 :

var finalObj = {
    "Subgroup1": null,
    "Subgroup2": null,
    "Subgroup3": {
        "subgroup5": {
            "subgroup6": {
                "subgroup7": {
                    "subgroup8": null
                }
            }
        }
    }
};

与您的原始文件相比,这是在几乎没有丢失信息的情况下实现的。发生的损失是 , , 的顺序,它们现在是数组中无序元素的无序属性。同样,如果在任何级别有多个子组,它们也将是无序的。Subgroup1Subgroup2Subgroup3finalObj

  • 如果你能忍受这种约束,那么上面的方法将为你省去很多心痛。
  • 如果你不能忍受这个约束,那么,稍微考虑一下,仍然可以以正确的顺序提取子组。
于 2013-01-08T00:50:31.970 回答
1

不确定这是否是合并树对象的正确方法,但只是想得到您的反馈/建议......

我有一个递归函数,它根据 id 返回节点。我检查 parent id 和 child id ,如果 parent id 存在但找不到 child id 我将孩子添加到 parent。如果父ID不存在我创建一个新节点,如果孩子已经退出,我只是忽略那个孩子......

这样,我可以联合我的节点(通过循环)......欢迎提出建议!!!!

         var arrayObject=[];

            var ob =    {
                text: "root",
                id: 1,
                items: [
                    {
                        text: "child one",
                        id: 11,
                        items: [
                            {
                                text: "grand child 1",
                                id: 111,
                                items: []},
                            {
                                text: "grand child 2",
                                id: 112,
                                items: []}
                        ]},
                    {
                        text: "child two",
                        id: 12,
                        items: []}
                ]
            };

            function findObjectById(root, id) {
                if (root.items) {
                    for (var k in root.items) {
                        if (root.items[k].id == id) {
                            return root.items[k];
                        }
                        else if (root.items.length) {
                            return findObjectById(root.items[k], id);
                        }
                    }
                }
            };
            var newChild={
                text: "child x",
                id: 115,
                items: []
            };

            for(var i=0;i<2;i++){
                if(i==0){
                    var checkParent = findObjectById(ob, 11);
                    alert(JSON.stringify(checkParent));

                }else{
                    var checkParent = findObjectById(ob, 116);
                }
                if(checkParent) {
                    var checkChild=findObjectById(checkParent, newChild.id);
                    alert(JSON.stringify(checkChild));
                    if(!checkChild){
                        checkParent.items.push(newChild);
                    }
                    arrayObject.push(ob)
                }else{

                    arrayObject.push(newChild);
                }
            }
于 2013-01-08T20:40:22.540 回答