Estoy tratando de usar el nuevo objeto Map de Javascript EC6, ya que ya es compatible con las últimas versiones de Firefox y Chrome.
Pero lo encuentro muy limitado en la programación "funcional", porque carece de métodos clásicos de mapa, filtro, etc. que funcionen bien con un [key, value]
par. Tiene forEach pero eso NO devuelve el resultado de devolución de llamada.
Si pudiera transformarlo map.entries()
de un MapIterator en una matriz simple, podría usar el estándar .map
, .filter
sin hacks adicionales.
¿Hay una "buena" forma de transformar un iterador de Javascript en una matriz? En python es tan fácil como hacerlo list(iterator)
... ¡pero Array(m.entries())
devuelve una matriz con el iterador como primer elemento!
EDITAR
Olvidé especificar que estoy buscando una respuesta que funcione donde sea que funcione Map, lo que significa al menos Chrome y Firefox (Array.from no funciona en Chrome).
PD.
Sé que existe el fantástico wu.js pero su dependencia de traceur me desanima ...
fuente
Respuestas:
Está buscando la nueva
Array.from
función que convierte iterables arbitrarios en instancias de matriz:Ahora es compatible con Edge, FF, Chrome y Node 4+ .
Por supuesto, puede valer la pena definir
map
,filter
y métodos similares directamente en la interfaz del iterador, para que pueda evitar la asignación de la matriz. También es posible que desee utilizar una función generadora en lugar de funciones de orden superior:fuente
(value, key)
pares y no(value, index)
pares.yourTransformation = function([key, value], index) { … }
Map
sí tiene pares de valores clave. Por lo tanto, en mi humilde opinión, no tiene ningún sentido definir generalesmap
yfilter
funciones para iteradores. En su lugar, cada objeto iterable debe tener su propiamap
yfilter
funciones. Esto tiene sentido porquemap
yfilter
son operaciones de preservación de la estructura (quizás no,filter
peromap
ciertamente lo es) y, por lo tanto, las funcionesmap
yfilter
deben conocer la estructura de los objetos iterables sobre los que están mapeando o filtrando. Piénselo, en Haskell definimos diferentes instancias deFunctor
. =)[...map.entries()]
oArray.from(map.entries())
Es superfácil.
De todos modos, los iteradores carecen de reducción, filtro y métodos similares. Debe escribirlos usted mismo, ya que es más eficaz que convertir Map a array y viceversa. Pero no haga saltos Mapa -> Array -> Mapa -> Array -> Mapa -> Array, porque matará el rendimiento.
fuente
Array.from
ya ha sido cubierto por @Bergi.[iterator]
no funciona porque en Chrome crea una matriz con un soloiterator
elemento, y[...map.entries()]
no es una sintaxis aceptada en ChromeNo hay necesidad de transformar un
Map
en unArray
. Simplemente podría crearmap
yfilter
funciones paraMap
objetos:Por ejemplo, podría agregar una explosión (es decir, un
!
carácter) al valor de cada entrada de un mapa cuya clave es primitiva.También puede agregar
map
yfilter
métodosMap.prototype
para que se lea mejor. Aunque generalmente no se recomienda modificar los prototipos nativos, creo que se puede hacer una excepción en el caso demap
yfilter
paraMap.prototype
:Editar: En la respuesta de Bergi, creó funciones genéricas
map
yfilter
generadoras para todos los objetos iterables. La ventaja de usarlos es que, dado que son funciones generadoras, no asignan objetos iterables intermedios.Por ejemplo, las funciones my
map
yfilter
definidas anteriormente crean nuevosMap
objetos. Por lo tanto, llamarobject.filter(primitive).map(appendBang)
crea dos nuevosMap
objetos:Crear objetos iterables intermedios es costoso. Las funciones del generador de Bergi resuelven este problema. No asignan objetos intermedios, pero permiten que un iterador alimente sus valores perezosamente al siguiente. Este tipo de optimización se conoce como fusión o deforestación en lenguajes de programación funcionales y puede mejorar significativamente el rendimiento del programa.
El único problema que tengo con las funciones generadoras de Bergi es que no son específicas de los
Map
objetos. En cambio, se generalizan para todos los objetos iterables. Por lo tanto, en lugar de llamar a las funciones de devolución de llamada con(value, key)
pares (como esperaría al mapear sobre aMap
), llama a las funciones de devolución de llamada con(value, index)
pares. De lo contrario, es una excelente solución y definitivamente recomendaría usarla sobre las soluciones que proporcioné.Estas son las funciones específicas del generador que usaría para mapear y filtrar
Map
objetos:Se pueden usar de la siguiente manera:
Si desea una interfaz más fluida, puede hacer algo como esto:
Espero que ayude.
fuente
Map
objetos usando funcionesmap
y especializadasfilter
. La respuesta de Bergi demuestra el uso de genéricosmap
yfilter
funciones para todos los objetos iterables que no se pueden usar para transformarMap
objetos porqueMap
se pierden las claves del objeto.Array.from
no funciona en Chrome (¡mientras que Map e iteradores sí!). ¡Pero puedo ver que el enfoque es muy similar y podría agregar la función "toArray" a su grupo!toArray
función.Una pequeña actualización de 2019:
Ahora, Array.from parece estar disponible universalmente y, además, acepta un segundo argumento mapFn , que le impide crear una matriz intermedia. Esto básicamente se ve así:
fuente
Array.from
ya existe una respuesta con , esto es más adecuado para ser un comentario o una edición solicitada para esa respuesta ... ¡pero gracias!Puede usar una biblioteca como https://www.npmjs.com/package/itiriri que implementa métodos de tipo matriz para iterables:
fuente
Puede obtener la matriz de matrices (clave y valor):
Y luego, puede obtener valores fácilmente desde adentro, como por ejemplo las claves con el iterador de mapa.
fuente
También puede usar fluent-iterable para transformar en matriz:
fuente