[英]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.