0

let aUsers=[{"name":"goku"},{"name":"cell"},{"name":"vegeta"},{"name":"freezer"}]

aUsers.forEach((user,i)=>{
  if(user.name=="cell" || user.name=="freezer"){
    aUsers.splice(i,1); //this causes a problem..
  }
})

console.log(aUsers);

I know that I should use filter, but I don't know how to get my elements to be removed from the array at the same time my foreach runs.

I would know how to solve this problem, but after running the foreach, maybe there is a better way to do it.

how can I do it?

yavg
  • 2,761
  • 7
  • 45
  • 115
  • 1
    Because `filter` returns a new array, you can assign aUsers to the filter function. `aUsers = aUsers.filter( /.../ );`. – Rickard Elimää Dec 22 '20 at 04:34
  • Ironically, your example works - by happy accident. Perhaps you can modify the example to remove two adjacent elements, like try checking `if(user.name=="cell" || user.name=="vegeta")`, then you'll actually illustrate the problem. – Wyck Dec 22 '20 at 04:59

1 Answers1

3

Yes, you should use filter instead of forEach:

let aUsers=[{"name":"goku"},{"name":"cell"},{"name":"vegeta"},{"name":"freezer"}]

const newUsers = aUsers.filter(user => user.name !== "cell" && user.name !== "freezer");

console.log(newUsers);

If you must change the array in-place, then iterate backwards:

let aUsers=[{"name":"goku"},{"name":"cell"},{"name":"vegeta"},{"name":"freezer"}]

for (let i = aUsers.length - 1; i >= 0; i--) {
  if (['cell', 'freezer'].includes(aUsers[i].name)) {
    aUsers.splice(i, 1);
  }
}

console.log(aUsers);
CertainPerformance
  • 356,069
  • 52
  • 309
  • 320
  • just curious :) may i know why to iterate backwards ? – KcH Dec 22 '20 at 04:34
  • 3
    If you don't, then you'll be mutating the array while iterating over it. Splicing out element 1 while iterating over element 1 means that the next index is 2 - what *used* to be in 2 is now 1, so it doesn't get iterated over. – CertainPerformance Dec 22 '20 at 04:37
  • ahh makes sense ... thanks :) – KcH Dec 22 '20 at 04:38