iterators iterables backbone javascript arrays ecmascript-6 iterable babeljs

javascript - iterables - Convertir ES6 Iterable en matriz



iterators typescript (5)

Digamos que tiene un Javascript ES6 Iterable tipo matriz que sabe de antemano que tendrá una longitud finita, ¿cuál es la mejor manera de convertirlo en una matriz de Javascript?

La razón para hacerlo es que muchas bibliotecas js como el subrayado y lodash solo admiten matrices, por lo que si desea utilizar cualquiera de sus funciones en un Iterable, primero debe convertirse en una matriz.

En python puedes usar la función list (). ¿Hay un equivalente en ES6?


Resumen:

  • Array.from() función Array.from() , toma un iterable como en la entrada y devuelve una matriz del iterable.
  • Operador de propagación: ... en combinación con una matriz literal.

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 (porque se refieren a la misma matriz, se copió la referencia).

Solución para advertencia:

Podemos resolver el problema de tener copias poco profundas 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)


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}]


Puede usar 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 ]


Puede usar el método Array.from , que se está agregando en ES6, pero solo admite matrices y objetos iterables como Mapas y Conjuntos (también disponibles en ES6). Para los objetos normales, puede usar el método toArray de Underscore o el método toArray de lodash, ya que ambas bibliotecas en realidad tienen un gran soporte para objetos, no solo matrices. Si ya está usando guiones bajos o lodash, afortunadamente pueden manejar el problema por usted, además de agregar varios conceptos funcionales como mapa y reducción para sus objetos.


También puedes hacer:

let arr = []; for (let elem of gen(...)){ arr.push(elem); }

O "de la manera difícil" usando la función de generador ES5 + ( Fiddle funciona en 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 ciertamente no son recomendables y son simplemente una prueba de concepto.