如何在javascript中结合复杂对象?

时间:2013-01-07 22:44:00

标签: javascript jquery object merge treeview

我有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"
                        }]
                    }]
                }]
            }]
        }
    ]
}]

3 个答案:

答案 0 :(得分: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];

答案 1 :(得分:2)

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

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

不是使用属性textitems构建对象,而是使用文本作为项的关键项,作为其属性,提供更紧凑的数据结构。

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
                }
            }
        }
    }
};

与原始文件相比,几乎没有丢失信息。发生的损失是Subgroup1Subgroup2Subgroup3订单,它们现在是finalObj的无序属性,而不是数组的有序元素。同样,如果在任何级别都有多个子组,它们也将是无序的。

  • 如果你能忍受这种限制,那么上述方法将为你节省很多心痛。
  • 如果您不能忍受这种约束,那么,只需稍加思考,子组仍然可以按正确的顺序提取。

答案 2 :(得分:1)

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

我有一个递归函数,它根据id返回节点。我检查父ID和子ID,如果父ID存在但无法找到子ID我将子项添加到父级。如果父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);
                }
            }
相关问题