recorrer objeto multiplicar matriz manejo eliminar elementos elemento dinamico con array agrupar agregar javascript loops

objeto - multiplicar elementos de un array javascript



Recorrer la matriz y eliminar elementos, sin romper el bucle (12)

Tengo lo siguiente para bucle, y cuando uso splice() para eliminar un elemento, obtengo que los ''segundos'' no están definidos. Podría verificar si está indefinido, pero creo que probablemente haya una forma más elegante de hacerlo. El deseo es simplemente eliminar un elemento y seguir adelante.

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


Aquí hay otro ejemplo para el uso correcto del empalme. Este ejemplo está a punto de eliminar ''atributo'' de ''matriz''.

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


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 estás sacando del final porque los índices se conservarán cuando retrocedas.


Intente retransmitir una matriz en newArray cuando haga bucles:

var auctions = Auction.auctions; var auctionIndex; var auction; var newAuctions = []; for ( auctionIndex = 0; auctionIndex < Auction.auctions.length; auctionIndex++) { auction = auctions[auctionIndex]; if (auction.seconds >= 0) { newAuctions.push( auction); } } Auction.auctions = newAuctions;


La matriz se está volviendo a indexar cuando haces un .splice() , lo que significa que .splice() un índice cuando se elimina uno, y tu .length almacenado en caché está obsoleto.

Para solucionarlo, necesitarías disminuir i después de un .splice() , o simplemente iterar a la inversa ...

var i = Auction.auctions.length while (i--) { ... if (...) { Auction.auctions.splice(i, 1); } }

De esta manera, la nueva indexación no afecta al 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 más bajo que el punto actual.


Otra solución simple para digerir una serie de elementos una vez:

while(Auction.auctions.length){ // From first to last... var auction = Auction.auctions.shift(); // From last to first... var auction = Auction.auctions.pop(); // Do stuff with auction }


Recalcular la longitud cada vez a través del bucle en lugar de 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: añade una disminución en la sentencia if.


Si bien su pregunta es sobre la eliminación de elementos de la matriz que se está iterando y no sobre la eliminación de elementos (además de algún otro procesamiento) de manera eficiente, creo que uno debería reconsiderarlo si se encuentra en una situación similar.

La complejidad algorítmica de este enfoque es O(n^2) como función de empalme y el bucle for itera sobre la matriz (la función de empalme desplaza todos los elementos de la matriz en el peor de los casos). En su lugar, simplemente puede empujar los elementos requeridos a la nueva matriz y luego simplemente asignar esa matriz a la variable deseada (sobre la cual se iteró).

var newArray = []; for (var i = 0, len = Auction.auctions.length; i < len; i++) { auction = Auction.auctions[i]; auction.seconds--; if (!auction.seconds < 0) { newArray.push(auction); } } Auction.auctions = newArray;

Desde ES2015 podemos usar Array.prototype.filter para ajustarlo todo en una línea:

Auction.auctions = Auction.auctions.filter(auction => --auction.seconds >= 0);


Si está utilizando ES6 +, ¿por qué no usa el método Array.filter?

Auction.auctions = Auction.auctions.filter((auction) => { auction[''seconds''] --; return (auction.seconds > 0) })

Tenga en cuenta que la modificación del elemento de la matriz durante la iteración del filtro solo funciona para los objetos y no funcionará para la matriz de valores primitivos.



Ya hay muchas respuestas maravillosas en este hilo. Sin embargo, quería compartir mi experiencia cuando intenté resolver "eliminar el elemento nth de la matriz" en el contexto de ES5.

Las matrices de JavaScript tienen diferentes métodos para agregar / eliminar elementos de inicio o fin. Estos son:

arr.push(ele) - To add element(s) at the end of the array arr.unshift(ele) - To add element(s) at the beginning of the array arr.pop() - To remove last element from the array arr.shift() - To remove first element from the array

Esencialmente, ninguno de los métodos anteriores se puede usar directamente para eliminar el elemento nth de la matriz.

Un hecho que vale la pena notar es que esto contrasta con el uso del iterador java, en el cual es posible eliminar el elemento nth para una colección mientras se realiza la iteración.

Básicamente, esto nos deja con un solo método de matriz Array.splice para realizar la eliminación del elemento nth (también hay otras cosas que podría hacer con estos métodos, pero en el contexto de esta pregunta me estoy centrando en la eliminación de elementos):

Array.splice(index,1) - removes the element at the index

Aquí está el código copiado de la respuesta original (con comentarios):

var arr = ["one", "two", "three", "four"]; var i = arr.length; //initialize counter to array length while (i--) //decrement counter else it would run into IndexOutBounds exception { if (arr[i] === "four" || arr[i] === "two") { //splice modifies the original array arr.splice(i, 1); //never runs into IndexOutBounds exception console.log("Element removed. arr: "); } else { console.log("Element not removed. arr: "); } console.log(arr); }

Otro método digno de mención es Array.slice . Sin embargo, el tipo de retorno de este método son los elementos eliminados. Además esto no modifica la matriz original. Fragmento de código modificado de la siguiente manera:

var arr = ["one", "two", "three", "four"]; var i = arr.length; //initialize counter to array length while (i--) //decrement counter { if (arr[i] === "four" || arr[i] === "two") { console.log("Element removed. arr: "); console.log(arr.slice(i, i + 1)); console.log("Original array: "); console.log(arr); } }

Dicho esto, todavía podemos usar Array.slice para eliminar el elemento nth de la siguiente manera y, como puede observar, hay mucho más código (por lo tanto, ineficiente)

var arr = ["one", "two", "three", "four"]; var i = arr.length; //initialize counter to array length while (i--) //decrement counter { if (arr[i] === "four" || arr[i] === "two") { console.log("Array after removal of ith element: "); arr = arr.slice(0, i).concat(arr.slice(i + 1)); console.log(arr); } }

El método Array.slice es extremadamente importante para lograr la inmutabilidad en la programación funcional a la redux.


Auction.auction = Auction.auctions.filter(function(el) { return --el["seconds"] > 0; });


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); i--; len--; } }