有人可以解释为什么这行不通吗
function filterNumbers(arr) {
for (var i = 0; i < arr.length; i++) {
if(typeof arr[i] !== 'number') {
arr.splice(i, 1);
}
}
}
但是这样做:
function filterNumbers(arr) {
for (var i = arr.length - 1; i >= 0; i--) {
if (typeof arr[i] !== 'number') {
arr.splice(i, 1);
}
}
}
对我来说,功能似乎是相同的,我无法理解该功能。
我正在测试的输入数组是:
var arr = [1, 'a', 'b', 2];
答案 0 :(得分:1)
splice
会修改原始数组,因此,每次在数组上使用splice
时,都会更改其原始长度。这就是为什么它向后工作的原因,因为当您向后走时,您期望每次循环运行时长度值都会减小。
如果您正在寻找更好的解决方案,只需使用filter
函数从数组中提取数字即可。
function isNumber(obj) {
return obj !== undefined && typeof(obj) === 'number' && !isNaN(obj);
}
var newArr = arr.filter(isNumber);
答案 1 :(得分:1)
每个人都没有直接回答您的问题,而是继续提及篇幅。
您的代码:
function filterNumbers(arr) {
for (var i = 0; i < arr.length; i++) {
if(typeof arr[i] !== 'number') {
arr.splice(i, 1);
}
}
}
问题在于i
所引用的内容(确实起了一定的作用,但它们没有进一步说明)。当i
为1时,您引用的是数组的a
。然后,将其从数组中拼接出来,该数组现在有1个引用“ b”。在完成迭代之前,它仍然在for循环内。然后,将i
从1(现在正在引用b
)增加到2,然后再引用2 2
。
您可以通过使数组中的所有字母成为字母来进一步测试,然后您将看到如何跳过其他所有字母(['a', 'b', 'c', 'd', 'e', 'f']
将产生['b', 'd', 'f']
)。
要解决该问题,您必须根据循环内的操作来增加/减少i
。如果您进行拼接,则将i
减1或在循环中抛出else语句,并在else语句内而不是在每次迭代之后增加i
值。
答案 2 :(得分:-1)
数组的长度随着每个循环而变化,因此是个问题。
在工作函数中,这无关紧要,因为我们从数组的末尾开始。