Digamos que tenemos un Mapa: let m = new Map(); , usando m.values() devuelve un iterador de mapa.
Pero no puedo usar forEach() o map() en ese iterador e implementar un bucle while en ese iterador parece un antipatrón ya que ES6 ofrece funciones como map() .
Entonces, ¿hay alguna forma de usar map() en un iterador?
La forma más simple y menos eficiente de hacer esto es:
Array.from(m).map(([key,value]) => /* whatever */)Mejor todavía
Array.from(m, ([key, value]) => /* whatever */)) Array.from toma cualquier cosa iterable o similar a una matriz y la convierte en una matriz! Como señala Daniel en los comentarios, podemos agregar una función de mapeo a la conversión para eliminar una iteración y, posteriormente, una matriz intermedia.
El uso Array.from moverá su rendimiento de O(1) a O(n) como lo señala @hraban en los comentarios. Dado que m es un Map y no pueden ser infinitos, no tenemos que preocuparnos por una secuencia infinita. Para la mayoría de los casos, esto será suficiente.
Hay un par de otras formas de recorrer un mapa.
forEach m.forEach((value,key) => /* stuff */ )for..of var myMap = new Map(); myMap.set(0, 'zero'); myMap.set(1, 'one'); for (var [key, value] of myMap) { console.log(key + ' = ' + value); } // 0 = zero // 1 = onePodría definir otra función de iterador para recorrer esto:
function* generator() { for (let i = 0; i < 10; i++) { console.log(i); yield i; } } function* mapIterator(iterator, mapping) { for (let i of iterator) { yield mapping(i); } } let values = generator(); let mapped = mapIterator(values, (i) => { let result = i*2; console.log(`x2 = ${result}`); return result; }); console.log('The values will be generated right now.'); console.log(Array.from(mapped).join(',')); Ahora puede preguntarse: ¿por qué no usar Array.from en su lugar? Debido a que esto se ejecutará a través de todo el iterador, guárdelo en una matriz (temporal), itérelo nuevamente y luego realice la asignación. Si la lista es enorme (o incluso potencialmente infinita), esto conducirá a un uso de memoria innecesario.
Por supuesto, si la lista de elementos es bastante pequeña, usar Array.from debería ser más que suficiente.
La forma más simple y de mayor rendimiento es usar el segundo argumento de Array.from para lograr esto:
const map = new Map() map.set('a', 1) map.set('b', 2) Array.from(map, ([key, value]) => `${key}:${value}`) // ['a:1', 'b:2'] Este enfoque funciona para cualquier iterable no infinito . Y evita tener que usar una llamada separada a Array.from(map).map(...) que iteraría a través del iterable dos veces y sería peor para el rendimiento.