我想知道是否以及什么是可靠和/或标准的方法来迭代一个长度在循环内变化的数组。我问,因为每次我想要这样做时,我最终会选择不同的方法,例如。
for ( var i = 0; i < myarray.length; i++ ) {
if (myarray[i] === 'something') {
myarray.splice(i, 1);
// *to avoid jumping over an element whose index was just shifted back to the current i
i--;
}
}
或
var i = 0;
while (myarray[i]) {
if (myarray[i] === 'something') {
myarray.splice(i, 1);
} else {
i++;
}
}
这些是我发现自己这样做的方式,但我很好奇是否有标准方法。
答案 0 :(得分:23)
我发现在另一个方向上迭代更简单:
for (var i=myarray.length; i--; ) {
if (myarray[i] === 'something') myarray.splice(i, 1);
}
这样,您无需在删除时更改增量。
许多开发人员,特别是那些在JavaScript之前没有处理类C语言的开发人员,发现处理递减运算符的微妙之处令人困惑。我写的循环也可以写成
for (var i=myarray.length-1; i>=0; i--) {
答案 1 :(得分:0)
但是你选择这样做,从反向开始,倒计时最简单。它还取决于您的数组是否稀疏以及是否希望它保持稀疏。最简单的方法是创建一个可重用的函数和自己的库。你可以做到这一点。如果将compress
设置为true,那么您的数组将变为连续而非稀疏数组。此函数将删除所有匹配的值,并返回已删除元素的数组。
的Javascript
function is(x, y) {
if (x === y) {
if (x === 0) {
return 1 / x === 1 / y;
}
return true;
}
var x1 = x,
y1 = y;
return x !== x1 && y !== y1;
}
function removeMatching(array, value /*, compress (default = false)*/ ) {
var removed = [],
compress = arguments[2],
index,
temp,
length;
if (typeof compress !== "boolean") {
compress = false;
}
if (compress) {
temp = [];
length = array.length;
index = 0;
while (index < length) {
if (array.hasOwnProperty(index)) {
temp.push(array[index]);
}
index += 1;
}
} else {
temp = array;
}
index = 0;
length = temp.length;
while (index < length) {
if (temp.hasOwnProperty(index) && is(temp[index], value)) {
if (compress) {
removed.push(temp.splice(index, 1)[0]);
} else {
removed.push(temp[index]);
delete temp[index];
}
}
index += 1;
}
if (compress) {
array.length = 0;
index = 0;
length = temp.length;
while (index < length) {
if (temp.hasOwnProperty(index)) {
array.push(temp[index]);
}
index += 1;
}
}
return removed;
}
var test = [];
test[1] = 1;
test[50] = 2;
test[100] = NaN;
test[101] = NaN;
test[102] = NaN;
test[200] = null;
test[300] = undefined;
test[400] = Infinity;
test[450] = NaN;
test[500] = -Infinity;
test[1000] = 3;
console.log(test);
console.log(removeMatching(test, NaN));
console.log(test);
console.log(removeMatching(test, Infinity, true));
console.log(test);
输出
[1: 1, 50: 2, 100: NaN, 101: NaN, 102: NaN, 200: null, 300: undefined, 400: Infinity, 450: NaN, 500: -Infinity, 1000: 3]
[NaN, NaN, NaN, NaN]
[1: 1, 50: 2, 200: null, 300: undefined, 400: Infinity, 500: -Infinity, 1000: 3]
[Infinity]
[1, 2, null, undefined, -Infinity, 3]
上