Digamos que você tenha um Iterable Javascript ES6 semelhante a um array que você sabe de antemão que terá comprimento finito. Qual é a melhor maneira de convertê-lo em um Array Javascript?
A razão para fazer isso é que muitas bibliotecas js, como sublinhado e lodash, suportam apenas Arrays, portanto, se você deseja usar qualquer uma de suas funções em um Iterable, primeiro ele deve ser convertido em um Array.
Em python, você pode apenas usar a função list (). Existe um equivalente no ES6?
javascript
arrays
ecmascript-6
iterable
babeljs
Michael Bylstra
fonte
fonte
Array.from(iterable)
, consulte ECMA-262 ed 6 draft .Respostas:
Você pode usar Array.from ou o operador spread .
Exemplo:
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 ]
fonte
let m = new Map()
estrutura de dados ES6 : para obter apenas os valores do Mapa, useArray.from
ou espalhe o operadorm.values()
, mesmo param.keys()
. Caso contrário, você vai ter uma matriz de matrizes:[[key, value], [key, value]]
.Resumo:
Array.from()
função, ele pega um iterável como na entrada e retorna uma matriz do iterável....
em combinação com um 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);
Advertência ao copiar matrizes:
Esteja ciente do fato de que, por meio desses métodos acima, apenas uma cópia superficial é criada quando queremos copiar um array. Um exemplo irá esclarecer o problema potencial:
let arr = [1, 2, ['a', 'b']]; let newArr = [ ...arr ]; console.log(newArr); arr[2][0] = 'change'; console.log(newArr);
Aqui, por causa do array aninhado, a referência é copiada e nenhum novo array é criado. Portanto, se alterarmos o array aninhado do array antigo, essa mudança será refletida no novo array (porque eles se referem ao mesmo array, a referência foi copiada).
Solução para advertência:
Podemos resolver o problema de ter cópias rasas criando um clone profundo do array usando
JSON.parse(JSON.stringify(array))
. Por exemplo: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)
fonte
Você pode usar o método Array.from , que está sendo adicionado no ES6, mas só oferece suporte a arrays e objetos iteráveis como Maps e Sets (também disponíveis no ES6). Para objetos regulares, você pode usar o método toArray de Underscore ou o método toArray de Lodash, uma vez que ambas as bibliotecas têm um grande suporte para objetos, não apenas arrays. Se você já está usando sublinhado ou lodash, então felizmente eles podem resolver o problema para você, além de adicionar vários conceitos funcionais como mapear e reduzir para seus objetos.
fonte
A abordagem a seguir é testada 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}]
fonte
<<Your_Array>> = [].concat.apply([], Array.from( <<Your_IterableIterator>> ));
fonte
Você também pode fazer:
let arr = []; for (let elem of gen(...)){ arr.push(elem); }
Ou "da maneira mais difícil" usando a função do gerador ES5 + ( Fiddle funciona no Firefox atual):
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); }
Ambas as abordagens certamente não são recomendáveis e são apenas uma prova de conceito.
fonte