recorrer example create crear javascript ecmascript-6

example - map set javascript



ES6: ¿Es peligroso eliminar elementos de Set/Map durante la iteración de Set/Map? (2)

El código seguro para el new Set() puede verse como:

let items = []; for (let item of set) if (isBad(item)) items.push(item); for (let item of items) set.delete(item)

¿Puedo simplificar el código para:

for (let item of set) if (isBad(item)) set.delete(item);

El código seguro para el new Map() puede verse como:

let keys = []; for (let [key, val] of map) if (isBadKey(key) || isBadValue(val)) keys.push(key); for (let key of keys) map.delete(key)

¿Puedo simplificar el código para:

for (let [key, val] of map) if (isBadJey(key) || isBadValue(val)) map.delete(key)


Sí, puedes simplificarlo, es totalmente seguro.

  • Conjuntos y mapas siempre se iteran en orden de inserción
  • La eliminación de un elemento no afecta la posición de ningún iterador: puede visualizar la forma de la colección que no se modifica, solo se vacía.
  • Por lo tanto: los elementos que se eliminan y aún no se han iterado no se iterarán
  • Los elementos que ya han sido iterados y eliminados (como en su caso) no afectarán a nada más que a otras iteraciones / búsquedas.
  • Los elementos que se agregan (y que aún no forman parte de la colección) durante la iteración siempre serán iterados

De ese último punto se deduce que lo único peligroso sería hacer algo como

const s = new Set([1]); for (let x of s) { s.delete(x); s.add(1); }

pero no debido a un comportamiento indefinido o acumulación de memoria, sino debido al bucle infinito.


Yo diría que sí, es seguro. Cuando recorre el Conjunto / Mapa utilizando for ... of debajo del capó, el bucle pasa por @@iterator . E .next() opera solo con .next() : no hay índices y no importa lo que esté antes de la posición actual. Sólo un siguiente elemento es importante.

Entonces, hasta que elimine los elementos "frente a" la posición actual del iterador, es seguro hacerlo.