Supongamos que tiene un Javascript ES6 Iterable similar a una matriz que sabe de antemano que tendrá una longitud finita, ¿cuál es la mejor manera de convertir eso en una matriz Javascript?
La razón para hacerlo es que muchas bibliotecas js, como el subrayado y lodash, solo admiten Arrays, por lo que si desea utilizar alguna de sus funciones en un Iterable, primero debe convertirlo en un Array.
En Python, puede usar la función list (). ¿Existe un equivalente en ES6?
javascript
arrays
ecmascript-6
iterable
babeljs
Michael Bylstra
fuente
fuente
Array.from(iterable)
, ver ECMA-262 ed 6 borrador .Respuestas:
Puede utilizar Array.from o el operador de propagación .
Ejemplo:
let x = new Set([ 1, 2, 3, 4 ]); let y = Array.from(x); console.log(y); // = [ 1, 2, 3, 4 ] let z = [ ...x ]; console.log(z); // = [ 1, 2, 3, 4 ]
fuente
let m = new Map()
la estructura de datos de ES6 : para obtener solo los valores del mapa, useArray.from
o extienda el operadorm.values()
, lo mismo param.keys()
. De lo contrario, obtendrá una matriz de matrices:[[key, value], [key, value]]
.Resumen:
Array.from()
, toma un iterable como en input y devuelve una matriz del iterable....
en combinación con un literal de matriz.const map = new Map([[ 1, 'one' ],[ 2, 'two' ]]); const newArr1 = [ ...map ]; // create an Array literal and use the spread syntax on it const newArr2 = Array.from( map ); // console.log(newArr1, newArr2);
Advertencia al copiar matrices:
Tenga en cuenta el hecho de que a través de estos métodos anteriores solo se crea una copia superficial cuando queremos copiar una matriz. Un ejemplo aclarará el problema potencial:
let arr = [1, 2, ['a', 'b']]; let newArr = [ ...arr ]; console.log(newArr); arr[2][0] = 'change'; console.log(newArr);
Aquí, debido a la matriz anidada, la referencia se copia y no se crea una nueva matriz. Por lo tanto, si mutamos la matriz anidada de la matriz anterior, este cambio se reflejará en la nueva matriz (debido a que se refieren a la misma matriz, se copió la referencia).
Solución de advertencia:
Podemos resolver el problema de tener copias superficiales creando un clon profundo de la matriz usando
JSON.parse(JSON.stringify(array))
. Por ejemplo:let arr = [1, 2, ['a', 'b']] let newArr = Array.from(arr); let deepCloneArr = JSON.parse(JSON.stringify(arr)); arr[2][0] = 'change'; console.log(newArr, deepCloneArr)
fuente
Puede usar el método Array.from , que se agrega en ES6, pero solo admite matrices y objetos iterables como Mapas y Conjuntos (que también vienen en ES6). Para objetos regulares, puede usar el método toArray de Underscore o el método toArray de lodash, ya que ambas bibliotecas tienen un gran soporte para objetos, no solo matrices. Si ya está utilizando subrayado o lodash, afortunadamente ellos pueden manejar el problema por usted, además de agregar varios conceptos funcionales como mapa y reducción para sus objetos.
fuente
El siguiente enfoque se prueba para Maps:
const MyMap = new Map([ ['a', 1], ['b', 2], ['c', 3] ]); const MyArray = [...MyMap].map(item => { return {[item[0]]: item[1]} }); console.info( MyArray ); //[{"a", 1}, {"b", 2}, {"c": 3}]
fuente
<<Your_Array>> = [].concat.apply([], Array.from( <<Your_IterableIterator>> ));
fuente
También puedes hacer:
let arr = []; for (let elem of gen(...)){ arr.push(elem); }
O "por las malas" usando la función de generador ES5 + ( Fiddle funciona en el Firefox actual):
var squares = function*(n){ for (var i=0; i<n; i++){ yield i*i; } } var arr = []; var gen = squares(10); var g; while(true){ g = gen.next(); if (g.done){ break; } arr.push(g.value); }
Sin embargo, ambos enfoques no son recomendables y son simplemente una prueba de concepto.
fuente