user2316667 user2316667 - 7 months ago 28
Javascript Question

How To Remove All Odd Numbers In An Array Using Javascript?

Can someone debug this code? I cannot for the life of me find the (run-time) error:

function generate_fibonacci(n1, n2, max, out){
var n = n1+n2;
if(n<max){
out.push(n);
generate_fibonacci(n2, n, max, out);
}
}

function generate_fibonacci_sequence(max){
var out = [1];
generate_fibonacci(0, 1, max, out);
return out;
}

function remove_odd_numbers(arr){
for (var i = 0; i < arr.length; i++) {
if(!(arr[i]%2==0)){
arr.splice(i, 1);
}
}
return arr;
}

function sum(array){
var total = 0;
for (var i = 0; i < array.length; i++) {
total+=array[i];
}
return total;
}

var fib_sq = generate_fibonacci_sequence(4000000);

console.log("Before: " + fib_sq);

remove_odd_numbers(fib_sq);

console.log("After: " + fib_sq);

console.log("WTH?: " + remove_odd_numbers([1,2,3,4,5,6,7,8,9]));


Output:

Before: 1,1,2,3,5,8,13,21,34,55,89,144,233,377,610,987,1597,2584,4181,6765,10946,17711,28657,46368,75025,121393,196418,317811,514229,832040,1346269,2178309,3524578
After: 1,2,5,8,21,34,89,144,377,610,1597,2584,6765,10946,28657,46368,121393,196418,514229,832040,2178309,3524578
WTH?: 2,4,6,8
[Finished in 0.3s]


I'm going crazy or something. For some reason, all odd numbers are not being removed. But as you can see at the end, it works perfectly. I have no idea what is going on.

Answer

The problem in the original code is that when you remove the first 1 at index 0, the array gets shifted; now arr[i] is contains the second 1; but you just step over it.

You need to use while instead of if here, or copy to a separate list. This is an example for splicing:

function remove_odd_numbers1(arr){
    for (var i = 0; i < arr.length; i++) {
        // here
        while (arr[i] % 2) {
            arr.splice(i, 1);
        }
    }
    return arr;
}

But it will be slow though. Better to create a new array:

function remove_odd_numbers2(arr){
    var rv = [];
    for (var i = 0; i < arr.length; i++) {
        if (! (arr[i] % 2)) {
            rv.push(arr[i]);
        }
    }
    return rv;
}

Generally the best algorithm however is to use the same array, if the original is not needed, so that no extra memory is required (though on javascript this is of a bit dubious value):

function remove_odd_numbers3(arr){
    var out = 0; 
    for (var i = 0; i < arr.length; i++) {
        if (! (arr[i] % 2)) {
            arr[out++] = arr[i]; 
        }
    }
    arr.length = out;
    return arr;
}

Notice however that unlike the splice algorithm, this runs in O(n) time.

Also, the Array.prototype.filter() is not bad, being a builtin. It also creates a new array and thus is comparable to the 2.

Comments