Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何删除阵列中重复对象的两个实例_Javascript_Arrays_Object - Fatal编程技术网

Javascript 如何删除阵列中重复对象的两个实例

Javascript 如何删除阵列中重复对象的两个实例,javascript,arrays,object,Javascript,Arrays,Object,我有一个对象数组。我试图找到重复的对象,然后删除该对象的两个实例 现在我正在使用这种方法: function checkForDups(data){ for(var i = 0; i < data.length; i++){ for(var j = i+1; j < data.length; j++){ if(data[j].number === data[i].number){ data.splice(j,1);

我有一个对象数组。我试图找到重复的对象,然后删除该对象的两个实例

现在我正在使用这种方法:

function checkForDups(data){
    for(var i = 0; i < data.length; i++){
      for(var j = i+1; j < data.length; j++){
        if(data[j].number === data[i].number){
          data.splice(j,1);
          data.splice(i,1);
        }
      }
    }
    return data;
  }
功能检查(数据){
对于(变量i=0;i
我认为问题在于,它只检查索引大于当前位置的重复项。这意味着不会检查阵列中“在其后面”的对象是否存在重复。目前,我通过这个函数运行数组几次,以获得所需的结果。然而,这显然是非常低效的。我怎样才能更有效地实现我想要的结果

我认为问题在于,它只检查索引大于当前位置的重复项。这意味着不会检查阵列中“在其后面”的对象是否存在重复

不,这是一个简单的优化,因为等式关系的对称性。通过向前搜索并删除前面的所有重复项,任何当前项都不能是前一项的重复项,否则它将被删除

但是,有些事情你没有注意到:

  • 从阵列中拼接(删除)项目时,将移动所有后续项目,并且阵列将更改其长度。要真正检查数组中的所有项,在删除时需要减少(或:不增加)计数器变量,以便访问与已删除项位于同一位置的新项(刚删除的位置需要重新访问)
  • 在找到重复项后,您可能希望
    中断内部循环,否则您将比较并删除完全不同的项
  • 您尚未明确当数组中有两个以上相同排序的重复项时,算法应该做什么。当他们的号码是奇数时留下一个?感谢您的评论。
    要删除所有现有的重复项,您需要继续搜索,但不得立即删除
    i
    th元素,否则您将没有任何东西可与FutureOn进行比较,或者您甚至可能多次删除
    i
    th项(请参见#2)
因此,此修改应适合:

function removeAllDups(data) {
    // leaves only items in the array that appeared a single time
    // removes everything whose .number can be found multiple times
    for (var i = 0; i < data.length; i++) {
        var found = false,
            num = data[i].number;
        for (var j = i+1; j < data.length; j++) {
            if (data[j].number === num) {
                found = true;
                data.splice(j--, 1);
            }
        }
        if (found) {
            data.splice(i--, 1);
        }
    }
    return data;
}
函数removeAllDups(数据){
//仅在数组中保留一次出现的项
//删除可以多次找到其.number的所有内容
对于(变量i=0;i
这里有一个替代实现。这仅使用两次通过阵列,并在>2的情况下删除所有重复:

请注意,这假设支持ES5方法-
Array#some
函数#bind
。如果您需要支持较旧的浏览器,ES5垫片或下划线库将符合要求。

您可以使用:

例子
您可以试试。

您能发布一个示例数组来产生意外的结果吗?请注意,这只适用于基本值(通常:所有可以转换为不同字符串的内容)。OP通过其
.number
属性测试(对象)项的相等性。当发现重复项时,我希望它删除该重复项的两个实例。例如,假设我有一个数组,看起来像
code
[{name:“foo”,number:1},{name:“bar”,number:2},{name:“foo”,number:1}]
code
我只想让它返回
code
[{name:“bar”,number:2}]
code
对不起,我刚刚重读了你的回答,意识到我对你的最后一点反应不正确。您刚刚让我意识到,我的主要问题之一是,在某些情况下,我有3个对象实例,但没有实现任何解释。如果有3个实例,我希望所有实例都被删除。非常感谢,这非常有效!但是,我不完全理解为什么在拼接方法中更改j和I的值。似乎合乎逻辑的是,您需要在索引处拼接数据[j].number==num的项,然后需要减少i和j,以考虑已删除的索引。是的,这就是所做的。请注意,我使用了
--
作为后缀运算符,即
splice()
将传递原始值。啊,我明白了。再次感谢您的回复!这很有帮助,也很有见地。
function removeDupes(arr, test) {
    test = test || function(a, b) { return a === b; };

    function find(cache, element) {
        return cache.some(test.bind(null, element));
    }

    var seen = [];
    var dupes = [];
    var len = arr.length;
    var x;
    var current;

    // First pass - find dupes
    for (x = 0; x < len; x++) {
        current = arr[x];
        if (find(seen, current)) {
            dupes.push(current);
        } else {
            seen.push(current);
        }
    }

    // Second pass: remove dupes. Reverse iteration saves headaches here
    for (x = len - 1; x >= 0; x--) {
        current = arr[x];
        if (find(dupes, current)) {
            arr.splice(x, 1);
        }
    }
}
removeDupes(arr, function(a, b) {
    return a.number == b.number;
});
function checkForDups(data) {
  return (
    _.map(
      _.filter(
        _.pairs(
          _.countBy(data)
        ), function(v) {return v[1] == 1}
      ), function(v) {return ~~v[0]}
    )
  )
}
>> console.log(checkForDups([0,1,2,3,0,1,0,4]))
[2, 3, 4]