Recorriendo la matriz y eliminando elementos, sin romper el bucle
Tengo el siguiente bucle for, y cuando lo uso splice()
para eliminar un elemento, obtengo que "segundos" no está definido. Podría comprobar si no está definido, pero creo que probablemente haya una forma más elegante de hacerlo. El deseo es simplemente eliminar un elemento y continuar.
for (i = 0, len = Auction.auctions.length; i < len; i++) {
auction = Auction.auctions[i];
Auction.auctions[i]['seconds'] --;
if (auction.seconds < 0) {
Auction.auctions.splice(i, 1);
}
}
La matriz se vuelve a indexar cuando realiza un .splice()
, lo que significa que omitirá un índice cuando se elimine uno y su caché .length
quedará obsoleto.
Para solucionarlo, necesitaría disminuir i
después de a .splice()
o simplemente iterar en reversa...
var i = Auction.auctions.length
while (i--) {
...
if (...) {
Auction.auctions.splice(i, 1);
}
}
De esta manera, la reindexación no afecta el siguiente elemento de la iteración, ya que la indexación afecta solo a los elementos desde el punto actual hasta el final de la matriz, y el siguiente elemento de la iteración es inferior al punto actual.
Este es un problema bastante común. La solución es hacer un bucle hacia atrás:
for (var i = Auction.auctions.length - 1; i >= 0; i--) {
Auction.auctions[i].seconds--;
if (Auction.auctions[i].seconds < 0) {
Auction.auctions.splice(i, 1);
}
}
No importa si los sacas del final porque los índices se conservarán a medida que retrocedas.
Vuelva a calcular la longitud cada vez que recorra el bucle en lugar de hacerlo solo al principio, por ejemplo:
for (i = 0; i < Auction.auctions.length; i++) {
auction = Auction.auctions[i];
Auction.auctions[i]['seconds'] --;
if (auction.seconds < 0) {
Auction.auctions.splice(i, 1);
i--; //decrement
}
}
De esa manera no excederás los límites.
EDITAR: agregó una disminución en la declaración if.