Convertir ES6 Iterable en Array

100

Supposons que vous ayez un Javascript ES6 Iterable de type tableau dont vous savez à l'avance qu'il aura une longueur limitée, quel est le meilleur moyen de le convertir en un tableau Javascript?

La raison en est que de nombreuses bibliothèques js telles que le soulignement et le lodash ne prennent en charge que les tableaux, donc si vous souhaitez utiliser l'une de leurs fonctions sur un Iterable, il doit d'abord être converti en un tableau.

En python, vous pouvez simplement utiliser la fonction list (). Existe-t-il un équivalent dans ES6?

Michael Bylstra
la source
26
Array.from(iterable), voir ECMA-262 ed 6 draft .
RobG

Réponses:

156

Vous pouvez utiliser Array.from ou l' opérateur de diffusion .

Exemple:

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 ]

XåpplI'-I0llwlg'I -
la source
2
Presque la même chose s'applique à la structure de let m = new Map()données ES6 : pour obtenir uniquement les valeurs de la carte, utilisez Array.fromou répartissez l'opérateur sur m.values(), idem pour m.keys(). Sinon, vous obtiendrez un tableau de tableaux: [[key, value], [key, value]].
Nik Sumeiko
17

Sommaire:

  • Array.from() fonction, il prend un itérable comme en entrée et retourne un tableau de l'itérable.
  • Opérateur de propagation: ...en combinaison avec un littéral de tableau.

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); 

Mise en garde lors de la copie de tableaux:

Soyez conscient du fait que via ces méthodes ci-dessus, seule une copie superficielle est créée lorsque nous voulons copier un tableau. Un exemple clarifiera le problème potentiel:

let arr = [1, 2, ['a', 'b']];

let newArr = [ ...arr ];

console.log(newArr);

arr[2][0] = 'change';

console.log(newArr);

Ici, en raison du tableau imbriqué, la référence est copiée et aucun nouveau tableau n'est créé. Par conséquent, si nous mutons le tableau imbriqué de l'ancien tableau, ce changement sera reflété dans le nouveau tableau (car ils font référence au même tableau, la référence a été copiée).

Solution de mise en garde:

Nous pouvons résoudre le problème des copies superficielles en créant un clone profond du tableau à l'aide de JSON.parse(JSON.stringify(array)). Par exemple:

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)

Willem van der Veen
la source
12

Vous pouvez utiliser la méthode Array.from , qui est en cours d'ajout dans ES6, mais ne prend en charge que les tableaux et les objets itérables comme les cartes et les ensembles (également disponibles dans ES6). Pour les objets réguliers, vous pouvez utiliser de Souligné toArray méthode ou méthode toArray de lodash, puisque les deux bibliothèques ont fait un grand soutien pour les objets, et pas seulement des tableaux. Si vous utilisez déjà un trait de soulignement ou un lodash, ils peuvent heureusement gérer le problème à votre place, en plus d'ajouter divers concepts fonctionnels tels que la carte et la réduction pour vos objets.

Colin Hartwig
la source
3

L'approche suivante est testée pour 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}]
romain
la source
Pas ce qui a été demandé - voir le tableau. De manière
João Antunes
0
 <<Your_Array>> = [].concat.apply([], Array.from( <<Your_IterableIterator>> ));
Dionis Oros
la source
-4

Vous pouvez également faire:

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

Ou "à la dure" en utilisant la fonction de générateur ES5 + ( Fiddle fonctionne dans Firefox actuel):

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);
}

Ces deux approches ne sont cependant certainement pas recommandables et ne sont qu'une preuve de concept.

CodeManX
la source