1

以下のように 3 つの異なるオブジェクト (obj1,2,3) があり、3 つのオブジェクトの結合 (一意のツリー リスト) である finalObj を形成しようとしています。

これを達成するための最良の方法が何であるかはわかりません..

編集: ここではテキストが重要です。同じテキストを持つ親ノードが既に存在する場合は、無視してその子ノードに移動し、この子ノードが存在するかどうかを確認する必要があります。そうでない場合は、この子ノードを既存の親ノードにアタッチします...

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、それぞれが 1 つしかアイテムを含まないため、冗長です。obj2obj3

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に基づいてノードを返す再帰関数があります。親 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);
                }
            }
于 2013-01-08T20:40:22.540 に答える