在另一个数组中查找项目并从数组中删除匹配的项目

时间:2017-02-28 13:56:04

标签: javascript

我有两个数组,其中包含如下记录:

var cars = ["Saab", "Volvo", "BMW"]; 

var cars1 = ["Saab", "Volvo", "BMW"]; 

现在我想从Cars1中删除匹配的元素,所以最后我的Cars1数组将如下所示:

var cars = ["Saab", "Volvo", "BMW"]; 

var cars1 = ["Saab", "Volvo", "BMW"]; 

 for (var i = 0; i < cars1.length; i++) {
                for (var j = 0; j < cars.length; j++) {
                    if (cars1[i] == cars[j]) {
                        cars1.splice(i, 1);
                        break;
                    }
                }
            }
console.log(cars1)

预期输出:

 var cars1 = []; 

我没有得到预期的输出。

5 个答案:

答案 0 :(得分:3)

使用简单的功能方法来节省空间并使其更清晰我建议将Array.prototype.filterArray.prototype.indexOf结合使用,如下所示:

var cars = ["Saab", "Volvo", "BMW"]; 

var cars1 = ["Saab", "Volvo", "BMW", "VW"];

cars1 = cars1.filter(car => cars.indexOf(car) < 0)

console.log(cars1)

filter方法调用每个元素的传递回调,如果回调返回false,则返回true返回元素时将不返回该元素。请注意,filter方法返回一个新数组,并不会修改当前数组!感谢@ denys-séguret提到它!

indexOf返回传递元素的索引。如果未找到,则返回-1。这就是为什么要过滤所有元素,索引为< 0,只返回cars数组中尚未存在的元素。

答案 1 :(得分:2)

您遗漏了一些项目,因为在您进行迭代时,已删除的项目将替换为下一项目。只需循环另一种方式, i 减少:

var cars = ["Saab", "Volvo", "BMW"]; 

var cars1 = ["Saab", "Volvo", "BMW"]; 

 for (var i=cars1.length; i--;) {
                for (var j = 0; j < cars.length; j++) {
                    if (cars1[i] == cars[j]) {
                        cars1.splice(i, 1);
                        break;
                    }
                }
            }
console.log(cars1)

请注意,您并不需要显式的双循环。可能的替代方案之一是使用indexOf。另一个(在大数组的情况下更有效)是将cars1的内容放入Set的实例中。如果你不需要保持相同的数组,当然还有filter

以下是设置和减少的方式(当汽车阵列很大时,这是一种非常有效的解决方案):

var cars = ["Saab", "Volvo", "BMW"]; 
var cars1 = ["Saab", "Volvo", "BMW"];
 
var set = cars.reduce((s,c) => s.add(c), new Set);
cars1 = cars1.filter(c => !set.has(c)); 
console.log(cars1);

对于古董浏览器:

var cars = ["Saab", "Volvo", "BMW"]; 
var cars1 = ["Saab", "Volvo", "BMW"];
 
var set = cars.reduce(function(s,c){
     s[c] = true;
     return s;
}, Object.create(null));
cars1 = cars1.filter(function(c){
     return !set[c];
}); 
console.log(cars1);

答案 2 :(得分:1)

您要做的事情称为difference。相反的是intersection

&#13;
&#13;
var cars = ["Saab", "Volvo", "BMW", "Skoda"]; 

var cars1 = ["Saab", "Volvo", "BMW"]; 

function diff(arr1, arr2) {
  return arr1.filter(x => arr2.indexOf(x) === -1)
}

function intersec(arr1, arr2) {
  return arr1.filter(x => arr2.indexOf(x) > -1)
}

console.log(
  diff(cars, cars1),
  intersec(cars, cars1)
);
&#13;
&#13;
&#13;

答案 3 :(得分:1)

你得到的结果是错误的,因为每个slice(),里面的元素都在改变它们的索引。因此,在第一个循环之后,Volvo将获得0索引,并且实际上已经处理了具有0索引的项目,因此该函数不会对其进行操作。这就是它在功能之后留在里面的原因。

我建议您使用Array#filter

&#13;
&#13;
var cars = ["Saab", "Volvo", "BMW"],
    cars1 = ["Saab", "Volvo", "BMW"]; 
    
    var result = cars.filter(v => cars1.indexOf(v) == -1);
    console.log(result);
&#13;
&#13;
&#13;

答案 4 :(得分:0)

在第一次调用cars1.splice(i,1)之后,cars1只有一个元素,因此继续使用外循环没有多大意义。 为了使代码更清晰,我建议使用indexOf而不是内部循环。

var cars = ["Saab", "Volvo", "BMW"];
var cars1 = ["Saab", "Volvo", "BMW"];

for (var i = 0; i < cars.length; i++) {
  var carPositionInCars1 = cars1.indexOf(cars[i]);
  if (carPositionInCars1 != -1) {
    cars1.splice(carPositionInCars1, 1);
  }
}
console.log(cars1);