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.

1
  • Use filter() instead of forEach(). Commented Jun 11, 2019 at 16:55

2 Answers 2

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)

Sign up to request clarification or add additional context in comments.

2 Comments

@TylerRoper i have added, but trying to form a better explanation for it
No worries, good answer!
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

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.