javascript dictionary syntax ecmascript-6 iterator

javascript - Usando map() en un iterador



map javascript (6)

La forma más simple y menos eficaz 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 Daniel señala 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 de Array.from moverá su rendimiento de O(1) a O(n) como @hraban señala en los comentarios. Como 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.

Usando para forEach

m.forEach((value,key) => /* stuff */ )

Usando para 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 = one

Digamos que tenemos un mapa: let m = new Map(); , utilizando m.values() devuelve un iterador de mapa.

Pero no puedo usar forEach() o map() en ese iterador e implementar un ciclo while en ese iterador parece un antipatrón ya que ES6 ofrece funciones como map() .

Entonces, ¿hay alguna manera de usar map() en un iterador?


La forma más simple y más Array.from 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 iteración no infinita . Y evita tener que usar una llamada separada a Array.from(map).map(...) que iteraría por el iterable dos veces y sería peor para el rendimiento.


Podrí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) { while (true) { let result = iterator.next(); if (result.done) { break; } yield mapping(result.value); } } 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 Array.from lugar? Como esto se ejecutará en todo el iterador, guárdelo en una matriz (temporal), repítalo nuevamente y luego realice la asignación. Si la lista es enorme (o incluso potencialmente infinita), esto conducirá a un uso innecesario de la memoria.

Por supuesto, si la lista de elementos es bastante pequeña, usar Array.from debería ser más que suficiente.


Podría usar itiriri que implementa métodos de tipo matriz para iterables:

import { query } from ''itiriri''; let m = new Map(); // set map ... query(m).filter([k, v] => k < 10).forEach([k, v] => console.log(v)); let arr = query(m.values()).map(v => v * 10).toArray();


Puede recuperar un iterador sobre el iterable, luego devolver otro iterador que llame a la función de devolución de llamada de mapeo en cada elemento iterado.

const map = (iterable, callback) => { return { [Symbol.iterator]() { const iterator = iterable[Symbol.iterator](); return { next() { const r = iterator.next(); if (r.done) return r; else { return { value: callback(r.value), done: false, }; } } } } } }; // Arrays are iterable console.log(...map([0, 1, 2, 3, 4], (num) => 2 * num)); // 0 2 4 6 8


Iterando sobre un mapa

1) Iterar sobre las teclas del mapa

Map ofrece el método de claves () que podemos usar para iterar en todas las claves.

for (const k of m.keys()) { console.log(k) }

2) iterar sobre los valores del mapa

El objeto Map ofrece el método de valores () que podemos usar para iterar en todos los valores:

for (const v of m.values()) { console.log(v) }

3) Iterar sobre la clave del mapa, pares de valores

El objeto Map ofrece el método de entradas () que podemos usar para iterar en todos los valores:

for (const [k, v] of m.entries()) { console.log(k, v) }

También podemos simplificar a

for (const [k, v] of m) { console.log(k, v) }