簡體   English   中英

如何使用JavaScript刪除數組中的所有奇數?

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

有人可以調試此代碼嗎? 我一生都找不到(運行時)錯誤:

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]));

輸出:

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]

我快瘋了。 由於某些原因,不會刪除所有奇數。 但是,正如您在最后看到的那樣,它可以完美運行。 我不知道發生了什么。

原始代碼中的問題是,當您刪除索引0處的第一個1時,數組會移位; 現在arr[i]包含第二個1 但你只是跨過它。

您需要使用while代替此處,或者復制到單獨的列表中。 這是一個拼接示例:

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

但這會很慢。 最好創建一個新數組:

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;
}

通常,最好的算法是使用相同的數組(如果不需要原始數組),因此不需要額外的內存(盡管在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;
}

但是請注意,與拼接算法不同,此算法運行時間為O(n)

另外,Array.prototype.filter()不錯,是內置的。 它還創建了一個新數組,因此可以與2媲美。

我不確定這一點,但是我懷疑使用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;
}

編輯:您應該使用@Jack建議的本機filter功能。 我將這個答案作為參考。

這是一種非常簡單,快速的方法。 使用您的數據,只需48毫秒即可完成。 希望這可以幫助..

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

因為splice()修改了數組,所以下一次迭代時索引將關閉; 您需要減少循環變量,使用Ant 提出while循環,或像Crazy Train 提到的那樣向后迭代。

就是說,使用splice()很麻煩,因為它可以就地修改數組。 也可以使用過濾器功能輕松實現此功能:

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

這將創建並返回僅包含偶數值的新數組。

鑒於此功能的最新性,請檢查兼容性部分,如何處理IE <9的瀏覽器。許多流行的庫,例如jQuery,下划線等,都為您解決了這一問題。

更新資料

與其之后過濾數組,不如在執行遞歸時僅添加偶數,將提高內存效率:

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);
    }
});

我沒有傳遞out數組,而是傳遞了一個在生成新序列值時要調用的函數。 過濾是在該回調內部完成的。

來自“ Tabetha Moe”的ES6版本答案

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM