javascript 如何使用Javascript删除数组中的所有奇数?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18305431/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-27 11:23:55  来源:igfitidea点击:

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

javascript

提问by user2316667

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.

我快疯了什么的。出于某种原因,所有奇数都没有被删除。但是正如您在最后看到的那样,它运行良好。我不知道发生了什么。

回答by Antti Haapala

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

原始代码中的问题是,当您删除1索引 0 处的第一个时,数组会移位;现在 arr[i]包含第二个1;但你只是跨过它。

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

您需要在此处使用 while 而不是 if ,或复制到单独的列表。这是一个拼接的例子:

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):

但是,通常最好的算法是使用相同的数组,如果不需要原始数组,则不需要额外的内存(尽管在 javascript 上这有点可疑):

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.

但是请注意,与拼接算法不同,这会O(n)及时运行。

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

此外, Array.prototype.filter() 也不错,是内置的。它还创建了一个新数组,因此与 2 相当。

回答by plalx

I'm not sure about this, however I doubt using spliceis efficient compared to creating a new array.

我不确定这一点,但是我怀疑splice与创建新数组相比,使用是否有效。

function remove_odd_numbers(arr) {
    var notOdd = [],
        i = 0,
        len = arr.length,
        num;

    for (; i < len; i++) {
        !((num = arr[i]) % 2) && notOdd.push(num);
    }

    return notOdd;
}

EDIT: You should probably use the native filterfunction, as suggested by @Hyman. I leave this answer as a reference.

编辑:您可能应该filter按照@Hyman 的建议使用本机函数。我留下这个答案作为参考。

回答by Tabetha Moe

Here is a really simple, fast way to do it. Using your data, it only took 48ms to complete. Hope this helps..

这是一个非常简单,快速的方法。使用您的数据,只需 48 毫秒即可完成。希望这可以帮助..

function noOdds(values){
  return values.filter(function (num) {
    return num % 2 === 0;
  });
}

回答by Ja?ck

Because splice()modifies the array, your index will be off in the next iteration; you need to either decrease the loop variable, use a whileloop like Antti proposedor iterate backwards like Crazy Train mentioned.

因为splice()修改了数组,你的索引将在下一次迭代中关闭;您需要减少循环变量,使用while像 Antti提议的循环或像 Crazy Train提到的那样向后迭代。

That said, the use of splice()is awkward to work with because it modifies the array in-place. This functionality can be easily accomplished using a filterfunction as well:

也就是说,使用splice()是很尴尬的,因为它会就地修改数组。使用过滤器功能也可以轻松实现此功能:

function remove_odd_numbers(arr) 
{
    return arr.filter(function(value) {
        return value % 2 == 0;
    });
}

This creates and returns a new array with only the even values.

这将创建并返回一个只有偶数值的新数组。

Given the recency of this function, check the compatibility sectionhow to handle browsers IE < 9. Many popular libraries, such as jQuery, underscore, etc. take care of this for you.

鉴于此功能的新近,请查看兼容性部分如何处理 IE < 9 的浏览器。许多流行的库,例如 jQuery、下划线等,都会为您处理此问题。

Update

更新

Instead of filtering the array afterwards, it would be more memory efficient to only add the even values as you perform the recursion:

与其在之后过滤数组,不如在执行递归时只添加偶数值,从而提高内存效率:

function generate_fibonacci(previous, current, max, callback)
{
    var next = previous + current;

    if (next < max) {
        callback(next);
        generate_fibonacci(current, next, max, callback);
    }
}

function generate_fibonacci_sequence(max, callback)
{
    callback(1);
    callback(1);
    generate_fibonacci(1, 1, max, callback);
}

var out = [];
generate_fibonacci_sequence(4000000, function(value) {
    if (value % 2 == 0) {
        out.push(value);
    }
});

Instead of passing the outarray, I'm passing a function to be called whenever a new sequence value is generated; the filtering is done inside that callback.

out我没有传递数组,而是传递一个在生成新序列值时要调用的函数;过滤是在该回调中完成的。

回答by Aminetech84

ES6 version from "Tabetha Moe" answer

ES6 版本来自“Tabetha Moe”的回答

function noOdds(arr) {
    return arr.filter(value => value % 2 === 0);
}