2013-06-26 30 views
7

Zastanawiam się, czy i jakie jest wiarygodnym i/lub standardowy sposób iteracja tablicę którego długość zmienia się wewnątrz pętli. Pytam, ponieważ w końcu wybieram inną metodę, aby to zrobić za każdym razem, kiedy chcę to zrobić, np.Pętla przez tablicy podczas usuwania elementów

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--; 
    } 
} 

lub

var i = 0; 
while (myarray[i]) { 
    if (myarray[i] === 'something') { 
    myarray.splice(i, 1); 
    } else { 
    i++; 
    } 
} 

Są sposoby, znajdę się w ten sposób, ale jestem ciekaw, czy tam jest standardowym podejściem.

+0

Czy można sprawdzić ten [http://stackoverflow.com/questions/9882284/looping-through-array-and- usuwanie elementów bez łamania pętli] Odpowiedź? –

+1

Możesz kontynuować swoją iterację do przodu w pierwszym przykładzie i umieścić swój słupek zmniejszający "i" bezpośrednio w wywołaniu '.splice()': 'myarray.splice (i--, 1);' –

Odpowiedz

22

znajdę prostsze iteracyjne w innym kierunku:

for (var i=myarray.length; i--;) { 
    if (myarray[i] === 'something') myarray.splice(i, 1); 
} 

W ten sposób nie trzeba zmieniać przyrost podczas wyjmowania.

Wielu deweloperów, zwłaszcza tych, którzy nie zajmują się języków C-jak przed JavaScript, uważają, że jest mylące, aby radzić sobie z subtelnościami Operator dekrementacji. Pętla pisałem można również zapisać jako

for (var i=myarray.length-1; i>=0; i--) { 
+0

to jest niesamowite, dziękuję –

+0

+1 zadałem podobne pytanie w wywiadzie dzisiaj rano ;-) najlepsze jest to nawet nie myślałem o tym rozwiązaniu –

+0

ta jest zdecydowanie zalecany sposób iterację kolekcji, które będą miały elementy usunięte. Robię to w dowolnym języku. – jlafay

0

jednak zdecydujesz się to zrobić, zaczynając w odwrocie i odliczany jest najprostsze. Zależy to również od tego, czy twoja tablica jest rzadka i czy chcesz, aby pozostała ona rzadka. Najłatwiej jest stworzyć sobie funkcję wielokrotnego użytku i własną bibliotekę. Możesz to zrobić. Jeśli ustawisz compress na true, twoja tablica stanie się tablicą ciągłą, a nie rzadką. Ta funkcja usunie wszystkie dopasowane wystąpienia wartości i zwróci tablicę usuniętych elementów.

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); 

Wyjście

[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] 

Na jsfiddle

Powiązane problemy