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?


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 ]


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)


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.


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

Nicht was gefragt wurde - siehe Array.from way
João Antunes

0
 <<Your_Array>> = [].concat.apply([], Array.from( <<Your_IterableIterator>> ));

-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.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.