Saltar al contenido

Cómo quitar el elemento de array en forEach loop?

Si encuentras algo que no comprendes puedes comentarlo y trataremos de ayudarte lo mas rápido que podamos.

Solución:

¿Parece que estás intentando hacer esto?

Iterar y mutar un array usando Array.prototype.splice

var pre = document.getElementById('out');

function log(result) 
  pre.appendChild(document.createTextNode(result + 'n'));


var review = ['a', 'b', 'c', 'b', 'a'];

review.forEach(function(item, index, object) 
  if (item === 'a') 
    object.splice(index, 1);
  
);

log(review);

Lo que funciona bien para un caso simple en el que no tiene 2 de los mismos valores que los adyacentes array artículos, de lo contrario, tiene este problema.

var pre = document.getElementById('out');

function log(result) 
  pre.appendChild(document.createTextNode(result + 'n'));


var review = ['a', 'a', 'b', 'c', 'b', 'a', 'a'];

review.forEach(function(item, index, object) 
  if (item === 'a') 
    object.splice(index, 1);
  
);

log(review);

Entonces, ¿qué podemos hacer con este problema al iterar y mutar un array? Bueno, la solución habitual es trabajar a la inversa. Usando ES3 mientras, pero puede usarlo para azúcar si lo prefiere

var pre = document.getElementById('out');

function log(result) 
  pre.appendChild(document.createTextNode(result + 'n'));


var review = ['a' ,'a', 'b', 'c', 'b', 'a', 'a'],
  index = review.length - 1;

while (index >= 0) 
  if (review[index] === 'a') 
    review.splice(index, 1);
  

  index -= 1;


log(review);

Ok, pero querías usar los métodos de iteración de ES5. Bueno, una opción sería usar Array.prototype.filter pero esto no muta el original array pero crea una nueva, por lo que si bien puede obtener la respuesta correcta, no es lo que parece haber especificado.

También podríamos usar ES5 Array.prototype.reduceRight, no por su propiedad reductora sino por su propiedad de iteración, es decir, iterar en reversa.

var pre = document.getElementById('out');

function log(result) 
  pre.appendChild(document.createTextNode(result + 'n'));


var review = ['a', 'a', 'b', 'c', 'b', 'a', 'a'];

review.reduceRight(function(acc, item, index, object) 
  if (item === 'a') 
    object.splice(index, 1);
  
, []);

log(review);

O podríamos usar ES5 Array.protoype.indexOf así.

var pre = document.getElementById('out');

function log(result) 
  pre.appendChild(document.createTextNode(result + 'n'));


var review = ['a', 'a', 'b', 'c', 'b', 'a', 'a'],
  index = review.indexOf('a');

while (index !== -1) 
  review.splice(index, 1);
  index = review.indexOf('a');


log(review);

Pero específicamente desea usar ES5 Array.prototype.forEach, entonces, ¿qué podemos hacer? Bueno, necesitamos usar Array.prototype.slice para hacer una copia superficial del array y Array.prototype.reverse para que podamos trabajar a la inversa para mutar el original array.

var pre = document.getElementById('out');

function log(result) 
  pre.appendChild(document.createTextNode(result + 'n'));


var review = ['a', 'a', 'b', 'c', 'b', 'a', 'a'];

review.slice().reverse().forEach(function(item, index, object) 
  if (item === 'a') 
    review.splice(object.length - 1 - index, 1);
  
);

log(review);

Finalmente, ES6 nos ofrece algunas alternativas adicionales, donde no necesitamos hacer copias superficiales y revertirlas. Cabe destacar que podemos utilizar generadores e iteradores. Sin embargo, el apoyo es bastante bajo en la actualidad.

var pre = document.getElementById('out');

function log(result) 
  pre.appendChild(document.createTextNode(result + 'n'));


function* reverseKeys(arr) 
  var key = arr.length - 1;

  while (key >= 0) 
    yield key;
    key -= 1;
  


var review = ['a', 'a', 'b', 'c', 'b', 'a', 'a'];

for (var index of reverseKeys(review)) 
  if (review[index] === 'a') 
    review.splice(index, 1);
  


log(review);

Algo a tener en cuenta en todo lo anterior es que, si estuviera quitando NaN del array entonces comparar con iguales no funcionará porque en Javascript NaN === NaN es false. Pero vamos a ignorar eso en las soluciones, ya que es otro caso de borde no especificado.

Ahí lo tenemos, una respuesta más completa con soluciones que todavía tienen casos extremos. El primer ejemplo de código sigue siendo correcto, pero como se ha dicho, no está exento de problemas.

Usar Array.prototype.filter en lugar de forEach:

var pre = document.getElementById('out');

function log(result) 
  pre.appendChild(document.createTextNode(result + 'n'));


var review = ['a', 'b', 'c', 'b', 'a', 'e'];
review = review.filter(item => item !== 'a');
log(review);

Aunque la respuesta de Xotic750 proporciona varios puntos buenos y posibles soluciones, a veces simple es mejor.

Conoce el array en la iteración se está mutando en la iteración en sí (es decir, eliminar un elemento => cambios de índice), por lo que la lógica más simple es retroceder a la antigua for (à la C idioma):

let arr = ['a', 'a', 'b', 'c', 'b', 'a', 'a'];

for (let i = arr.length - 1; i >= 0; i--) 
  if (arr[i] === 'a') 
    arr.splice(i, 1);
  


document.body.append(arr.join());

Si realmente lo piensas, un forEach es solo azúcar sintáctico para un for bucle … Entonces, si no te está ayudando, por favor deja de romperte la cabeza contra él.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *