Javascript:根据对象内部的值从数组中删除对象

时间:2019-06-11 16:42:11

标签: javascript

我已经建立了如下的数组对象结构

nestedArray = [ { source : "a" , target : "b", table : "ab" }, 
{ source : "c" , target : "d", table : "cd" }, 
{ source : "a" , target : "d", table : "cd" }, 
{ source : "a" , target : "f", table : "cd" }];

然后我在下面的代码中删除了sourcea的所有嵌套对象。


nestedArray.forEach(function(element) {
  if(element.source == "a") {
    nestedArray.splice(nestedArray.indexOf(element), 1) ;
  }
});

但是当我尝试在上述代码之后打印数组时,我仍然可以看到一个sourcea的对象。

> > nestedArray 
[ { source: 'c', target: 'd', table: 'cd' },  
 { source: 'a', target: 'f', table: 'cd' } ]
> >

我在这里错过了什么吗?任何建议,不胜感激。

2 个答案:

答案 0 :(得分:4)

  

为什么我的代码不起作用?

使用splice,您正在突变原始数组,并且更改了要循环的数组的长度,从而跳过了一些索引,即

  • 第一个匹配项位于索引0,因此,当您拼接其余元素的索引时,索引将减少1,因此,由于您已经在同一数组上循环,因此index的值迭代后将循环设置为1
  • 现在1处的元素是{source: 'a'...}而不是{source: c},所以现在当我们再次拼接时,索引减少1index的循环值设置为2迭代后
  • 现在在索引2上,但是该特定索引没有任何价值

您可以简单地使用过滤器

let nestedArray = [ { source : "a" , target : "b", table : "ab" }, 
{ source : "c" , target : "d", table : "cd" }, 
{ source : "a" , target : "d", table : "cd" }, 
{ source : "a" , target : "f", table : "cd" }];

let op = nestedArray.filter(({source})=> source !== 'a')

console.log(op)

答案 1 :(得分:1)

forEachslice的问题在于列表缩小,但索引保持不变,因此跳过了元素。相反,我建议filter

nestedArray = [ { source : "a" , target : "b", table : "ab" }, 
{ source : "c" , target : "d", table : "cd" }, 
{ source : "a" , target : "d", table : "cd" }, 
{ source : "a" , target : "f", table : "cd" }];

const result = nestedArray.filter(o => o.source !=='a');

console.log(result);

如果需要使用forEach而不是filter来创建新列表,请参见this answer