4

ネストされたオブジェクトの配列があります(これを使用してツリーにデータを入力します)。次のようになります。

var obj1= {
        text: "TreeRoot",
        items: [ {
            text: "subgroup1" ,
            items: [ {
                text: "subgroup2",
                items: [ {
                    text: "subgroup3",
                    items: [ {
                        text: "subgroup4",
                        items: [ {
                            text: "subgroup5"
                        }]
                    }]
                }]
            }]
        }]
    };

var obj2 = {
        text: "TreeRoot",
        items: [ {
            text: "subgroup1" ,
            items: [ {
                text: "subgroup2",
                items: [ {
                    text: "subgroup3",
                    items: [ {
                        text: "subgroup4",
                        items: [ {
                            text: "subgroup5"
                        }]
                    }]
                }]
            }]
        }]
    };


 var obj3= {
        text: "TreeRoot",
        items: [ {
            text: "subgroup1" ,
            items: [ {
                text: "subgroup2"
                }]
            }]
        }]
    };

var finalArray=[];
finalArray.push(obj1);
finalArray.push(obj2);
finalArray.push(obj3);

次に、textを使用して最終的な配列から重複するオブジェクトを削除する必要があります(つまり、配列からobj2を削除する必要があります)...

これは私が試したものです。

var arr = {};

for ( var i=0; i < finalPath.length; i++ )
     arr[finalArray[i]['text']] = finalArray[i];

finalArray= new Array();
for ( key in arr )
    finalArray.push(arr[key]);

誰かが私に可能な限り最善の方法を教えてもらえますか?

編集:

以下の解決策は機能すると思いますが、まだ完全にテストしていません...

var arr = {};

for ( var i=0; i < finalArray.length; i++ ){
    if(finalArray[i].items){
        for(var j=0;j<finalArray[i].items.length;j++){
            arr[finalArray[i].items[j]['text']] = finalArray[i];
        }
    }else{
        arr[finalArray[i]['text']] = finalArray[i];
    }
}


finalArray= new Array();
for ( key in arr )
    finalArray.push(arr[key])

ありがとう、バラニ

4

3 に答える 3

2

JSON は非常に使いやすく、コードをクリーンに保ちますが、おそらく多くの処理が必要になるでしょう。

問題を解決する別の方法があります。配列を調べて各ブランチを比較する再帰関数を作成できます。

function areEqual(a, b) {
    if( (a.items && !b.items) || (!a.items && b.items) ) return false;
    else if(!a.items && !b.items) return a.text == b.text ? true : false;
    else return (a.text == b.text) ? areEqual(a.items[0], b.items[0]) : false;
}

このコードは提供されたデータで機能しますが、(テキストだけでなく) 他の値をテストする場合は、おそらく関数を調整する必要があります。

areEqual(obj1, obj2) : true
areEqual(obj1, obj3) : false

編集:

これは関数の簡略化されたバージョンであり、(テキストだけでなく) 複数の要素を比較する必要がある場合はさらに優れています。

function areEqual(a, b) {
    var conditions = a.text == b.text /* && a.another_var == b.another_var */;

    if( typeof(a.items) != typeof(b.items) ) return false;
    if(a.items && b.items && conditions) return areEqual(a.items[0], b.items[0]);
    return conditions;
}
于 2013-01-11T00:45:28.877 に答える
1

申し訳ありませんが、オブジェクトの深さが 2 より大きい場合、コードは失敗すると思います。少なくとも、ロジックは非常に奇妙に思えます。2 つのオブジェクトが等しいかどうかをチェックするテストを定義してみませんか? 再帰テストを使用するか、単純に json バージョンで同等性をテストできます: 次のようなもの:

function are_equal(obj1,obj2) {
return JSON.stringify(obj1)==JSON.stringify(obj2);
}

そして、ここで応答を使用して、JavaScript 配列から重複を削除します

uniqueArray = finalArray.filter(function(elem, pos) {
return are_equal(elem,pos);
})

私はそれをテストしていません。これが役立つことを願っています。

于 2013-01-03T10:55:23.083 に答える
0

このコードを試してください:

var ObjList = [......]; /*All your objects*/
var dict = {}; /*Dictionary for duplicate elimination*/
for (var obj in ObjList) 
{
  dict[JSON.stringify(obj)] = JSON.stringify(obj);
}
var newObjList = [];
for (var key in dict)
{
  newObjList.push(key);
}

newObjListこれで、ツリーの深さに関係なく、すべてのユニークなアイテムが揃いました。

于 2013-01-03T15:41:05.897 に答える