2013-06-26 38 views
7

我不知道是否和什么是迭代一个数组,其长度在循环内是变化的可靠和/或标准的方式。我问,因为我最终选择了一种不同的方法来做到这一点,每次我想这样做,例如,遍历阵列删除元素时

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

你检查这[http://stackoverflow.com/questions/9882284/looping-through-array-and-删除项目,没有破环for]回答? –

+1

你可以让你的向前迭代的第一个例子,并把您的文章递减'i'直接在'.splice()'调用:'myarray.splice(我 - ,1);' –

回答

22

我找到简单的在另一个方向遍历:

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--) { 
+0

这是真棒,谢谢 –

+0

+1我问过类似的问题,在今天接受采访时上午;-)最好的部分是,即使我没想到这个解决方案 –

+0

这是绝对推荐的方式,通过一个集合,将有删除的项目迭代的。我用任何语言都能做到这一点。 – jlafay

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] 

jsfiddle