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
How To Remove All Odd Numbers In An Array Using 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 1
at 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 splice
is 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 filter
function, 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 while
loop 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 out
array, 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);
}