2013-06-26 169 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