2017-02-28 63 views
0

删除匹配的项目,我有两个阵列的记录,像下面:在另一个数组找到项目,然后从阵列

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 = []; 

我没有得到预期的输出。

+0

我不喜欢这里的大多数答案都没有试图理解OP的错误。 –

回答

2

您错过了一些项目,因为当您迭代时,删除的项目将被替换为下一个项目。只是循环的其他方式,与下降:你真的不

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

+0

Upvoted为您的慈善努力,帮助我。我在这两个阵列有1000个记录,所以你认为哪种方法更合适? –

+1

@学习在这种情况下使用该设置。我会更新,告诉你如何去做 –

+0

对不起,再次出现bug,但是这个设置和减少所有浏览器和旧浏览器的作品? –

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阵列中的元素。

+2

请注意这一重要区别:原始数组未更新。这可能很重要,取决于OP的需求(阵列通常是共享的)。你也不解释OP的错误。 –

+0

是的!这就是为什么我将'cars1'重新分配给过滤器调用的返回值。 – JoschuaSchneider

+1

是的,但当共享数组时这是不够的(这是使用拼接的最常见原因) –

1

你试图做的事叫做difference。相反的是intersection

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

1

你得到错误的结果,因为每slice(),里面的元素正在改变他们的指标。所以在第一个循环之后,Volvo将获得0索引,而实际上0索引已经被处理,所以该函数将不会对其进行操作。这就是为什么它在功能之后停留在内部。我建议你使用Array#filter

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

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

Pplease提供了一些关于您的代码实际执行的信息。你在哪里改进了OP代码,他做了什么错误的事情......只是从几条随机的代码行中学习,而没有任何解释就很难学习。 – Christoph