【问题标题】:Array.prototype.splice() not removing Objects while iteratingArray.prototype.splice() 在迭代时不删除对象
【发布时间】:2016-04-18 19:03:32
【问题描述】:

我正在处理一组mongodbObjectID 对象。我必须检查这个数组是否包含重复项,如果是,请删除它们。

这是我拥有的removeDuplicate 函数,它简单地循环具有两个索引的数组。如果两个对象相同,则splice() 函数将删除其中一个。

function removeDuplicates(array) {
    var a = array.concat(); // Copy object
    for(var i=0; i<a.length; ++i) {
      for(var j=i+1; j<a.length; ++j) {
        console.log(a[i] + " vs " + a[j]);
          if(a[i].equals(a[j]))
            console.log("removed : " + a.splice(j--, 1));
      }
    }
    return a;
}

假设我有一个简单的数组,其中包含两个相同的 ObjectID 对象。 然后我调用removeDuplicates 函数,传递数组。 最后,我打印出数组本身。

var array = [];

array.push(new ObjectID("56fc227026aed8e74a699b20"));
array.push(new ObjectID("56fc227026aed8e74a699b20"));

removeDuplicates(array);

console.log(array);

这是输出。如您所见,最后没有删除任何内容。

56fc227026aed8e74a699b20 vs 56fc227026aed8e74a699b20
removed : 56fc227026aed8e74a699b20
[ 56fc227026aed8e74a699b20, 56fc227026aed8e74a699b20 ]

我做错了什么?

【问题讨论】:

    标签: javascript arrays loops


    【解决方案1】:

    您是从副本中删除它,而不是从原件中删除。不过,您似乎正在记录原始记录,因此仍将包含重复项。

    【讨论】:

    • 哦,你是对的。我忘了抓住新对象......我的错
    【解决方案2】:

    一遍又一遍地拼接一个数组不是很好的方法,因为它必须为每次拼接分配新内存,并将结果复制到新内存。然后它必须 GC 旧内存

    但您可以一步完成;
    换一种方法怎么样:

    //an utility to be used as a filter:
    function removeDuplicates(v, i, arr) {
        while(i--) if( v.equals( arr[i] ) ) return false;
        return true;
    }
    
    var filteredArray = yourArray.filter(removeDuplicates);
    

    【讨论】:

    • 这是实现我想做的事情的一种非常聪明的方法。因为每次向数组插入新值时我都必须检查重复项,我认为您给我的方法将是一个完美的选择。
    • 不完全是,我认为这会很麻烦。为了检查一个数组是否已经包含一些 obj,我会使用这个:arr.some( obj.equals, obj )arr.some( obj.equals.bind(obj) )。也许是内联的,也许是封装到一些实用函数中,也许你将它与 arr.push() 结合起来,function add(arr, obj){ arr.some( obj.equals, obj ) || arr.push(obj); }
    猜你喜欢
    • 2014-07-12
    • 2020-07-30
    • 2011-07-17
    • 1970-01-01
    • 2019-02-12
    • 2016-12-02
    • 1970-01-01
    • 2016-01-02
    • 2015-10-05
    相关资源
    最近更新 更多