2

I am trying to remove an object from an array if a particular value for a key matches a given string:

Example data:

array = [{_id: "abc", test: "123"}, 
         {_id: "def", test: "123"},
         {_id: "ghi", test: "123"}];

Here is my loop:

for (var i = 0; i < array.length; i++) {
    var x = "123"
    if (array[i].test == x) {
       array.splice(i, 1)
    }
}

This should return an empty array but it's leaving one object in the array (the last one) and I've got no clue why.

2
  • I realise the problem now - third time around the loop, array.length = 1 and i = 2. What's the best solution? Commented Apr 11, 2016 at 23:53
  • 2
    Iterating backwards is one way to work around the problem. Change your loop header to: for ( var i = array.length; i--; ). That works because when you remove an element only the indices of elements past that one are affected; elements before it are not touched, so if you are iterating backwards, removing an element won't affect the index of future elements in your loop. Commented Apr 11, 2016 at 23:54

4 Answers 4

4

You must not increment i if you remove an element.

Suppose the array has two matching elements.

The first iteration, i = 0

i ==>>  element 1
        element 2

You then remove element 1, and increment i

        element 2
i ==>>   

There are many ways you can correct this. Here's an example that replaces your for loop with a while loop.

var i = 0;
while (i < array.length) {
    var x = "123"
    if (array[i].test == x) {
       array.splice(i, 1)
    } else {
       ++i;
    }
}
Sign up to request clarification or add additional context in comments.

Comments

2
array = [
  {id: "abc", test: "123"}, 
  {id: "def", test: "456"},
  {id: "ghi", test: "789"}
];
let x = "123";
let i = array.findIndex(data => data.test === x);
    if (i !== -1) {
        array.splice(i, 1);
    } else ...
console.log(array);

2 Comments

While this code may answer the question, providing additional context regarding why and/or how this code answers the question improves its long-term value.
Hello! Yes, I tried to explain it haha ​​the problem is that it is the first time that I leave a comment here and don't believe it, it was difficult for me because I tried to write and it said error. I don't understand! Sorry, thank you!
1

Figured it out:

array = array.filter(function(array) {
  var x = "123";
  return array.test !== x;
})

2 Comments

But that's not using splice, which seems to be the point of the exercise.
@RobG Cleaner and easier to use imho. I'm always open to new methods to solve a problem.
0

I have written a function that takes the index and event values from the html and processes in ts

app.component.html

<tr *ngFor="let container of containers; let i = index;" 
      [(ngModel)]="miningname"
            ngDefaultControl>
              <td>
    <input *ngIf="addMore" type="text" class = "form-control" 
     placeholder="Key" 
     [(ngModel)]="container.key2Name" 
       (ngModelChange)="textKeyChangedMore($event,i)">
</td></tr>

app.component.ts

  textKeyChangedMore(eventMore, indexMore) {


    var valueLength = this.selectedAPIName.length

      var i = indexMore+1;
      if (this.selectedAPIName[i].value == undefined ) {

        this.selectedAPIName.splice(indexMore + 1, 1, { key: eventMore, value: undefined });
      }
      else if (this.selectedAPIName[i].value !== undefined) {

        this.selectedAPIName.splice(indexMore + 1, 1, { key: eventMore, value: this.selectedAPIName[i].value });
      }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.