admin管理员组文章数量:1279182
I am trying to e up with another way to remove all of the odd numbers from an array. A friend was able to e up with this solution and I understand what it does, but I am failing to find another solution to it. Do you have any ideas for another solution to do this?
JavaScript
let myArray = [1,3,5,7,9,2,4,6,8];
let it = myArray.length;
for(let i=0; i<it; i++) {
for(let j=0; j<myArray.length; j++ )
if(myArray[j]%2 === 1){
myArray.splice(j,1)
break;
}
};
console.log(myArray);
I am trying to e up with another way to remove all of the odd numbers from an array. A friend was able to e up with this solution and I understand what it does, but I am failing to find another solution to it. Do you have any ideas for another solution to do this?
JavaScript
let myArray = [1,3,5,7,9,2,4,6,8];
let it = myArray.length;
for(let i=0; i<it; i++) {
for(let j=0; j<myArray.length; j++ )
if(myArray[j]%2 === 1){
myArray.splice(j,1)
break;
}
};
console.log(myArray);
Share
Improve this question
asked Mar 31, 2017 at 3:20
bemonbemon
1234 silver badges15 bronze badges
1
-
1
"another solution" - There are lots of possible solutions, but I doubt you can find anything simpler than
.filter()
. By the way, the solution shown may work, but it doesn't make much sense: the outer loop will run through to the original array length even after items are removed, and the inner loop always restarts with the first element so you're reprocessing elements for no reason. (Andit
is a terrible variable name.) – nnnnnn Commented Mar 31, 2017 at 3:25
3 Answers
Reset to default 8
let myArray = [1, 3, 5, 7, 9, 2, 4, 6, 8];
myArray = myArray.filter(e => e % 2 === 0)
console.log(myArray);
Your question asks how to "remove odds", not how to "keep evens" – the result is the same in this case, but the way you derive the answer could vary. There's not always a perfect opposite function that plugs directly into Array.prototype.filter
, so all answers here will be in the context of removing elements where we only a way to detect odd values – not keeping elements that are even. I'll detail a wide variety of ways to solve your problem, but first let's review your code
your friend's answer
I added a console.log
on your inner loop so you can see each element you're checking. It's easy to see that this solution is doing more work than it has to - there's no need to create more than 1 loop to iterate thru your array of numbers.
let myArray = [1,3,5,7,9,2,4,6,8]
let it = myArray.length
for(let i = 0; i < it; i++) {
for(let j = 0; j < myArray.length; j++ ) {
console.log('checking:', myArray[j])
if(myArray[j] % 2 === 1) {
myArray.splice(j,1)
break
}
}
}
console.log(myArray)
Also important, you need to be very mindful when changing the length of an array as you're iterating thru it. For example, if you call arr.splice(i,1)
, what effect does that have on your loop?
- all elements to the right of "i" will shift left 1 place
- the length of the array decreases by 1
So how should your loop acmodate for that?
- if all elements shift left after a splice, that means we need to re-check the same
i
once more because it now points to a new value - if the length decreases by 1, we need to change the loop exit condition to stop 1 iteration sooner
The mutRejectOdds
answer below addresses these issues
recursive function
highly readable and straightforward but not stack-safe
const isOdd = x => x & 1 === 1
const removeOdds = ([x,...xs]) => {
if (x === undefined)
return []
else if (isOdd(x))
return removeOdds(xs)
else
return [x, ...removeOdds(xs)]
}
let data = [1,2,3,4,5,6,7,8]
console.log(removeOdds(data)) // [2,4,6,8]
console.log(data) // [1,2,3,4,5,6,7,8]
linear iterative with accumulator
stack-safe and highly practical
const isOdd = x => x & 1 === 1
const removeOdds = xs => {
let acc = []
for (let x of xs)
if (!isOdd(x))
acc.push(x)
return acc
}
let data = [1,2,3,4,5,6,7,8]
console.log(removeOdds(data)) // [2,4,6,8]
console.log(data) // [1,2,3,4,5,6,7,8]
continuation passing style
brain-twisting but super fun recursive solution that could be put on a trampoline to make stack-safe
const isOdd = x => x & 1 === 1
const identity = x => x
const removeOdds = xs => {
const aux = ([x,...xs], k) => {
if (x === undefined)
return k([])
else if (isOdd(x))
return aux(xs, k)
else
return aux(xs, acc => k([x, ...acc]))
}
return aux(xs, identity)
}
let data = [1,2,3,4,5,6,7,8]
console.log(removeOdds(data)) // [2,4,6,8]
console.log(data) // [1,2,3,4,5,6,7,8]
higher-order function
similar to the recursive function, but instead accepts another argument which is a function of elements to skip - could be written in linear iterative style or continuation passing style too
const isOdd = x => x & 1 === 1
const reject = (f, [x,...xs]) => {
if (x === undefined)
return []
else if (f(x))
return reject(f, xs)
else
return [x, ...reject(f, xs)]
}
let data = [1,2,3,4,5,6,7,8]
console.log(reject(isOdd, data)) // [2,4,6,8]
console.log(data) // [1,2,3,4,5,6,7,8]
function position with Array.prototype.filter
uses the highly practical built-in Array.prototype.filter
but returns the opposite result using function position with not
const isOdd = x => x & 1 === 1
const p = f => g => x => f(g(x))
const not = x => !x
const reject = (f, xs) =>
xs.filter(p(not)(f))
let data = [1,2,3,4,5,6,7,8]
console.log(reject(isOdd, data)) // [2,4,6,8]
console.log(data) // [1,2,3,4,5,6,7,8]
linear iterative with in-place mutation
all methods I implemented above do not mutate the original data
- in some cases, if you had a particularly large array and you did not want to create a copy with odd values removed, you might wish to perform an in-place modification of data
this answer addresses the issues in your original code
const isOdd = x => x & 1 === 1
const mutRejectOdds = xs => {
for (let i = 0, len = xs.length; i < len; i++)
if (isOdd(xs[i]))
(xs.splice(i,1), i--, len--)
}
let data = [1,2,3,4,5,6,7,8]
console.log(mutRejectOdds(data)) // undefined
console.log(data) // [2,4,6,8]
If you only need support as far back as IE9 you can use the Array.prototype.filter method.
var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
var output = arr.filter(function(item) {
return item % 2 === 0;
});
Output will be a new array of the filtered values (Only even).
本文标签: javascriptRemove odd numbers in arrayStack Overflow
版权声明:本文标题:javascript - Remove odd numbers in array - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1741286867a2370322.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论