【问题标题】:Compare two Javascript Arrays and remove Duplicates比较两个 Javascript 数组并删除重复项
【发布时间】:2013-02-02 13:00:39
【问题描述】:

如果它有另一个数组的元素,还有其他更好的方法可以从一个数组中删除重复项吗?

<script>
var array1 = new Array("a","b","c","d","e","f");
var array2 = new Array("c","e");

for (var i = 0; i<array2.length; i++) {
    var arrlen = array1.length;
    for (var j = 0; j<arrlen; j++) {
        if (array2[i] == array1[j]) {
            array1 = array1.slice(0, j).concat(array1.slice(j+1, arrlen));
        }
    }
}
alert(array1);

</script>

【问题讨论】:

  • 我可能是错的,但我认为这不会是高性能的。你正在做 2 个循环

标签: javascript


【解决方案1】:
array1 = array1.filter(function(val) {
  return array2.indexOf(val) == -1;
});

或者,随着 ES6 的可用性:

array1 = array1.filter(val => !array2.includes(val));

filter() reference here

indexOf() reference here

includes() reference here

【讨论】:

  • 作为上述代码的旁注和解释:“indexOf:返回数组中等于指定值的元素的第一个(最小)索引,如果没有找到,则返回 -1。” (developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…)
  • 我喜欢它,但它肯定需要解释,或者至少需要一个链接将某人引导到解释它的正确位置。
  • 一段很棒的代码,但请注意,如果您有嵌套数组,它就不起作用。
  • 适用于唯一值列表,但如果列表中有重复值,例如比较“赎金票据”和杂志中的单词列表(假设大小写必须匹配并且必须有每个单词的正确数量)...
  • 带过滤器的漂亮灵魂。
【解决方案2】:

由于我无法理解的原因,诀窍是使外循环向下循环 (i--),内循环向上循环 (j++)。

请看下面的例子:

function test() {
  var array1 = new Array("a","b","c","d","e","f");
  var array2 = new Array("c","e");
  for (var i = array1.length - 1; i >= 0; i--) {
    for (var j = 0; j < array2.length; j++) {
      if (array1[i] === array2[j]) {
        array1.splice(i, 1);
        }
      }
    }
    console.log(array1)
  }

我怎么知道这个?见下文:

for( var i =myArray.length - 1; i>=0; i--){
  for( var j=0; j<toRemove.length; j++){
    if(myArray[i] === toRemove[j]){
      myArray.splice(i, 1);
    }
  }
}

var myArray = [
  {name: 'deepak', place: 'bangalore'}, 
  {name: 'chirag', place: 'bangalore'}, 
  {name: 'alok', place: 'berhampur'}, 
  {name: 'chandan', place: 'mumbai'}
];
var toRemove = [
  {name: 'deepak', place: 'bangalore'},
  {name: 'alok', place: 'berhampur'}
];

for( var i=myArray.length - 1; i>=0; i--){
    for( var j=0; j<toRemove.length; j++){
        if(myArray[i] && (myArray[i].name === toRemove[j].name)){
            myArray.splice(i, 1);
        }
    }
}

alert(JSON.stringify(myArray));

关于这一点,谁能解释为什么外循环需要向下循环(--)?

祝你好运!

【讨论】:

  • 您是否有理由不使用数组字面量、过滤器或包含?
  • 如何在不使用属性名称的情况下删除重复项。就像不指定任何数组 obj 名称。
  • @vishal 更改 array1[i] === array2[j] 以扩展项目的属性名称。现在是array1[i].propertyOfThisItem === array2[j].possiblyTheSameProperty
【解决方案3】:

使用Array.splice()

var array1 = ['1', '2', '3', '4', '5'];
var array2 = ['4', '5'];
var index;
for (var i=0; i<array2.length; i++) {
    index = array1.indexOf(array2[i]);
    if (index > -1) {
        array1.splice(index, 1);
    }
}

【讨论】:

    【解决方案4】:

    使用 Set.prototype 构造函数:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set

    let array1 = Array('a', 'b', 'c', 'd', 'e', 'f')
    let array2 = Array('c', 'e', 'g')
    let concat = array1.concat(array2) // join arrays => [ 'a', 'b', 'c', 'd', 'e', 'f', 'c', 'e', 'g' ]
    
    // Set will filter out duplicates automatically
    let set = new Set(concat) // => Set { 'a', 'b', 'c', 'd', 'e', 'f', 'g' }
    
    // Use spread operator to extend Set to an Array
    let result = [...set]
    console.log(result) // =>  [ 'a', 'b', 'c', 'd', 'e', 'f', 'g' ]
    

    【讨论】:

    • 这太棒了。使用 Set 和 MDN 链接中的示例函数可以实现非常聪明的联合(它回答了问题)、差异和交叉点
    • @Drenai 是的,如果你对对象进行字符串化,它适用于对象:)
    【解决方案5】:

    这是我的解决方案

    array1 = array1.filter(function(val) { return array2.indexOf(val.toString()) == -1; });

    【讨论】:

    • 最佳答案还不够吗?为什么需要额外的.toString()
    【解决方案6】:

    这是我在 ES6 中删除重复项的解决方案。

    let foundDuplicate = false;
    existingOptions.some(existingItem => {
      result = result.filter(item => {
        if (existingItem.value !== item.value) {
          return item;
        } else {
          foundDuplicate = true;
        }
      });
      return foundDuplicate;
    });
    

    我使用这种方法是因为在我的情况下,我有一个对象数组,而 indexOf 遇到了问题。

    【讨论】:

      【解决方案7】:
      window.onload = function () {
              var array1 = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm'];
              var array2 = ['c', 'h', 'k'];
              var array3 = [];
              var SecondarrayIndexcount = 0;
              for (var i = 0; i < array1.length; i++) {
                  for (var j = 0; j < array2.length; j++) {
                      if (array1[i] !== array2[j]) {
                          if (SecondarrayIndexcount === (array2.length - 1)) {
                              array3.push(array1[i]);
                              SecondarrayIndexcount = 0;
                              break;
                          }
                          SecondarrayIndexcount++;
                      }
                  }
              }
              for (var i in array3) {
                  alert(array3[i]);
              }
          }
      </script>
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-05-09
        • 2017-12-31
        • 2020-05-08
        • 1970-01-01
        • 2020-12-14
        • 1970-01-01
        • 2013-10-11
        • 1970-01-01
        相关资源
        最近更新 更多