1

I have an array:

var productIds = new Array("1","6","7","Product-Total","ccFirst","ccLast","email","ccExpMonth","ccExpYear","billingAddress","billingCity","billingState","billingZip");

I want to delete a value if it is not a number:

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

It seems the splice method is affecting the positions of the values.

I found this solution(Looping through array and removing items, without breaking for loop) which is what I think I need, but I can't figure out how to implement their answers for my code.

How can I fix my problem?

btw, I posted a more detailed jsFiddle: http://jsfiddle.net/fte3m/2/

Community
  • 1
  • 1
zeckdude
  • 15,877
  • 43
  • 139
  • 187
  • After you modify the array - its indexes are recalculated. So after you removed element with index `1` in array of 3 elements - there are elements with `0` and `1`, not `0` and `2` – zerkms Apr 11 '13 at 01:38
  • 2
    Your linked answer has the answer. ;-) – RobG Apr 11 '13 at 01:40
  • possible duplicate of [Looping through array and removing items, without breaking for loop](http://stackoverflow.com/questions/9882284/looping-through-array-and-removing-items-without-breaking-for-loop) – zerkms Apr 11 '13 at 01:41
  • 1
    You can probably use `isNaN(productIds[i])` instead of `isNaN(Number(productIds[i]))`. – Ted Hopp Apr 11 '13 at 01:47

1 Answers1

5

When you delete the entry at index i, you need to subtract 1 from i so the entry that was moved down is not skipped.

for(var i=0; i<productIds.length; i++){
   if(isNaN(productIds[i])) {  
       productIds.splice(i--,1);  // <-- Decrement i
   }
}

As RobG points out in his comment, it's easier to simply process the array in the other direction:

for(var i=productIds.length - 1; i>=0; i--){
   if(isNaN(productIds[i])) {
       productIds.splice(i,1);
   }
}

Alternatively, if you don't mind reassigning productIds to be a new array object and you are running JS 1.6 or later:

productIds = productIds.filter(function (id) {
    return !isNaN(id);
});

(Note that in the above, I just use isNaN(value) rather than isNaN(Number(value)). Whenever Number(value) would return NaN, isNaN(value) will return true, and vice versa. Note also that neither approach will filter out a null id, since Number(null)==0 and isNaN(null)==false. If you want to exclude null entries from the result, you will need to test for that separately.)

Ted Hopp
  • 232,168
  • 48
  • 399
  • 521