Konvertieren Sie ES6 Iterable in Array

93

Angenommen, Sie haben ein Array-ähnliches Javascript ES6 Iterable, von dem Sie im Voraus wissen, dass es endlich lang ist. Wie können Sie es am besten in ein Javascript-Array konvertieren?

Der Grund dafür ist, dass viele js-Bibliotheken wie Unterstrich und lodash nur Arrays unterstützen. Wenn Sie also eine ihrer Funktionen auf einem Iterable verwenden möchten, muss sie zuerst in ein Array konvertiert werden.

In Python können Sie einfach die Funktion list () verwenden. Gibt es ein Äquivalent in ES6?

Michael Bylstra
quelle
24
Array.from(iterable)siehe ECMA-262 ed 6 Entwurf .
RobG
Sie sollten diese Antwort akzeptieren. Es ist richtig.
Kleinfreund

Antworten:

146

Sie können Array.from oder den Spread-Operator verwenden .

Beispiel:

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 -
quelle
2
Fast das Gleiche gilt für die ES6- let m = new Map()Datenstruktur: Um nur Werte der Karte zu erhalten, verwenden Sie den Array.fromOperator oder verteilen Sie ihn m.values(), für m.keys(). Andernfalls erhalten Sie ein Array von Arrays : [[key, value], [key, value]].
Nik Sumeiko
15

Zusammenfassung:

  • Array.from() Funktion nimmt es eine iterable wie in Eingabe und gibt ein Array der iterable zurück.
  • Spread-Operator: ...in Kombination mit einem Array-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); 

Vorsichtsmaßnahme beim Kopieren von Arrays:

Beachten Sie, dass über diese Methoden nur eine flache Kopie erstellt wird, wenn Sie ein Array kopieren möchten. Ein Beispiel verdeutlicht das potenzielle Problem:

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

let newArr = [ ...arr ];

console.log(newArr);

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

console.log(newArr);

Hier wird aufgrund des verschachtelten Arrays die Referenz kopiert und kein neues Array erstellt. Wenn wir also das verschachtelte Array des alten Arrays mutieren, wird diese Änderung im neuen Array wiedergegeben (da sie sich auf dasselbe Array beziehen, wurde die Referenz kopiert).

Lösung für Vorbehalte:

Wir können das Problem der flachen Kopien lösen, indem wir mit einen tiefen Klon des Arrays erstellen JSON.parse(JSON.stringify(array)). Beispielsweise:

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
quelle
12

Sie können die Array.from- Methode verwenden, die in ES6 hinzugefügt wird, jedoch nur Arrays und iterierbare Objekte wie Maps und Sets unterstützt (auch in ES6 enthalten). Für reguläre Objekte können Sie die toArray- Methode von Underscore oder die toArray-Methode von lodash verwenden, da beide Bibliotheken tatsächlich eine hervorragende Unterstützung für Objekte bieten, nicht nur für Arrays. Wenn Sie bereits Unterstrich oder Lodash verwenden, können diese das Problem glücklicherweise für Sie lösen und verschiedene Funktionskonzepte wie Map und Reduce für Ihre Objekte hinzufügen.

Colin Hartwig
quelle
3

Der folgende Ansatz wurde für Karten getestet:

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}]
römisch
quelle
Nicht was gefragt wurde - siehe Array.from way
João Antunes
0
 <<Your_Array>> = [].concat.apply([], Array.from( <<Your_IterableIterator>> ));
Dionis Oros
quelle
-4

Sie könnten auch tun:

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

Oder "auf die harte Tour" mit der ES5 + Generatorfunktion ( Fiddle funktioniert im aktuellen Firefox):

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

Beide Ansätze sind jedoch sicherlich nicht empfehlenswert und lediglich ein Proof-of-Concept.

CodeManX
quelle