我正试图想出另一种方法来从数组中删除所有奇数。一位朋友能够提出这个解决方案,我理解它的作用,但我没有找到另一个解决方案。你对另一个解决方案有什么想法吗?
的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);
答案 0 :(得分:8)
let myArray = [1, 3, 5, 7, 9, 2, 4, 6, 8];
myArray = myArray.filter(e => e % 2 === 0)
console.log(myArray);
&#13;
答案 1 :(得分:2)
你的问题是如何“消除赔率”,而不是如何“保持平衡” - 在这种情况下结果是一样的,但你得出答案的方式可能会有所不同。直接插入Array.prototype.filter
并不总是有一个完美的相反函数,因此这里的所有答案都将在删除元素的上下文中,我们只能检测奇数值 - 不保持偶数元素。我将详细介绍解决问题的各种方法,但首先让我们回顾一下您的代码
您朋友的回答
我在你的内循环上添加了一个console.log
,这样你就可以看到你正在检查的每个元素。很容易看出这个解决方案正在做更多的工作 - 没有必要创建超过 1 循环来迭代你的数字数组。
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)
同样重要的是,当你通过迭代来改变数组的长度时,你需要非常谨慎。例如,如果你调用arr.splice(i,1)
,那对你的循环有什么影响?
那么你的循环应该如何适应呢?
i
,因为它现在指向一个新值以下mutRejectOdds
答案解决了这些问题
递归功能
高度可读性和直接但不是堆栈安全
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]
带累加器的线性迭代
堆栈安全且非常实用
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]
延续传球风格
大脑扭曲,但超级有趣的递归解决方案,可以放在蹦床上,使堆栈安全
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]
高阶函数
类似于递归函数,但是接受另一个参数,它是要跳过的元素的函数 - 可以用线性迭代样式或连续传递样式来编写
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]
使用Array.prototype.filter
函数组合
使用高度实用的内置 线性迭代与原位突变 我在上面实现的所有方法不都会改变原始 此答案解决了原始代码中的问题 Array.prototype.filter
但使用not
const isOdd = x => x & 1 === 1
const comp = f => g => x => f(g(x))
const not = x => !x
const reject = (f, xs) =>
xs.filter(comp(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]
data
- 在某些情况下,如果你有一个特别大的数组并且你不想创建副本< / em>删除了奇数值,您可能希望执行data
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]
答案 2 :(得分:0)
如果您只需要支持IE9,您可以使用Array.prototype.filter方法。
var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
var output = arr.filter(function(item) {
return item % 2 === 0;
});
输出将是过滤值的新数组(仅偶数)。