如何从包含嵌套对象的数组中删除重复项

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

现在我需要使用文本从我的最终数组中删除重复的对象(即,我应该从我的数组中删除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])

感谢您,Barani。

两个对象是否相等的规则是什么? - Aaron Kurtzhals
如果对象包含相同数量的节点/文本,则表示这两个对象相等... - Learner
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;
}

1

抱歉,但我认为如果对象的深度超过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);
})

我还没有测试过,希望这可以帮到你。


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 包含了您的所有唯一项,无论树有多深。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接