flowers
flowers

Reputation: 173

Removing negatives from JavaScript array

This is not removing negative integers from an array. I can't figure out why not...

for(var ii = 0; ii < diffs.length; ii++) {
     if(Number(diffs[ii]) < 0) {
       diffs.splice(ii, 1);
     }
   }

Upvotes: 0

Views: 1265

Answers (4)

Bergi
Bergi

Reputation: 664237

When removing item while traversing an array forward, you will need to adjust the loop variable or you skip the next element. The other possibility is to traverse backwards.

for (var i=0; i<diffs.length; i++)
    if (Number(diffs[i]) < 0)
        diffs.splice(i--, 1);

// OR

for (var i=diffs.length-1; i>=0; i--)
    if (Number(diffs[i]) < 0)
        diffs.splice(i, 1);

It might be easier (and maybe even faster) to create a new array and overwrite the diffs variable with it. This works very elegant with the filter() method:

var diffs = diffs.filter(function(diff) { return Number(diff) >= 0; });

Upvotes: 0

Stano
Stano

Reputation: 8939

The index can be fixed also like this:

for (ii = 0; ii < diffs.length; ii++) {
    if (Number(diffs[ii]) < 0) {
        removed.push(diffs[ii]);
        diffs.splice(ii, 1);
        ii--;
    }
}
console.log(diffs);
console.log(removed);

fiddle

As now I see, posted this answer too late again :)

Upvotes: 0

jfriend00
jfriend00

Reputation: 707158

You can't traverse the array upwards from 0 when you are modifying the array during the traversal because removing the current element will move the other elements down in the array and cause you to skip the next element.

A common way to solve this is to traverse the array elements in reverse order because the elements that are repositioned by removing the current element are ones that you have already traversed, not the ones the for loop is still going to process next:

for(var ii = diffs.length - 1; ii >= 0; ii--) {
    if(Number(diffs[ii]) < 0) {
        removed.push(diffs[ii]);
        diffs.splice(ii, 1);
    }
}

You also have to push the removed item BEFORE you remove it from the array.

Upvotes: 2

Dennis
Dennis

Reputation: 32598

You have two problems: 1) When you remove items in the array, you have to make sure you don't increment the counter (this can be avoided by counting from the end). 2) You have to store the result from splice and then add it to the removed array

for(var ii = diffs.length - 1; ii >= 0; ii--) {
    if(+diffs[ii] < 0) { // use the unary plus operator to convert to a number, just in case
        removed.push(diffs.splice(ii, 1)[0]); //splice returns an array - get the first and only element in it
    }
}

Upvotes: 2

Related Questions