1

I have built an array-object structure as below

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" }];

And I wrote below code to remove all nested objects where source is a.


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

But when I try printing the array after above code, I can still see an object with source as a.

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

Am I missing anything here ? Any suggestions greatly appreciated.

Raja G
  • 5,973
  • 14
  • 49
  • 82

2 Answers2

4

Why my code is not working ?

With splice you're mutating original array and which changes length of array you're looping on and in turn you skip some indexes, i.e.

  • first match is at index 0 so when you splice the remaining elements indexes it reduces by 1 so, but as you're looping already on the same array so index value of loop is set to 1 after iteration
  • Now element at 1 is {source: 'a'...} not {source: c} so now when we splice again the index reduces by 1 and index value of loop is set to 2 after iteration
  • so now on index 2, but there's no value at that particular index

You can simply use filter

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)
Code Maniac
  • 37,143
  • 5
  • 39
  • 60
1

The problem with a forEach and slice is the list shrinks but the index keeps going and so elements are skipped. Instead I'd recommend 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);

If a forEach is required instead of filter make a new list, see this answer

depperm
  • 10,606
  • 4
  • 43
  • 67