Aus irgendeinem Grund kann ich diese einfache Sache nicht in den MDN-Dokumenten finden (vielleicht fehlt sie mir nur).
Ich habe erwartet, dass das funktioniert:
const map = new Map({foo: 'bar'});
map.get('foo'); // 'bar'
... aber die erste Zeile wirft TypeError: (var)[Symbol.iterator] is not a function
Wie erstelle ich eine Karte aus einem einfachen Objekt? Muss ich es wirklich zuerst in ein Array von Arrays von Schlüssel-Wert-Paaren konvertieren?
javascript
ecmascript-6
Callum
quelle
quelle
Object.entries
wirklich ist der bessere Ansatz vorbeiObject.keys
, und Bergis Generatorfunktionsansatz ist etwas direkter als entwederObject.keys
oderObject.entries
.Antworten:
Ja, der
Map
Konstruktor verwendet ein Array von Schlüssel-Wert-Paaren.Object.entries
ist eine neue statische Objektmethode, die in ES2017 (19.1.2.5) verfügbar ist .Es ist derzeit in Firefox 46+ und Edge 14+ sowie in neueren Versionen von Chrome implementiert
Wenn Sie ältere Umgebungen unterstützen müssen und Transpilation für Sie keine Option ist, verwenden Sie eine Polyfüllung, wie die von Georg empfohlene:
quelle
Object.entries = obj => Object.keys(obj).map(k => [k, obj[k]])
Object.entries
landete in Node 7.x (ohne Flagge) übrigensBitte sehen Sie die Antwort von nils mit
Object.entries
und / oder die Antwort von bergi mit einer Generatorfunktion . ObwohlObject.entries
es noch nicht in der Spezifikation enthalten war, als die Frage gestellt wurde, befand es sich in Phase 4 , so dass es bereits im April 2016 (nur) sicher gefüllt und verwendet werden konnte. (Mehr zu den Stufen hier .) Und Generatorfunktionen waren in ES2015. Das OP hat ausdrücklich darum gebeten, Vermittler zu vermeiden, und obwohl der Generator dies nicht vollständig vermeidet, leistet er einen besseren Job als der unten stehende oder (geringfügig)Object.enties
.FWIW, mit
Object.entries
:[name, value]
Arrays, an die übergeben werden sollnew Map
Map
Konstruktor ruft eine Funktion für das Array auf, um einen Iterator abzurufen. Das Array erstellt ein Array-Interatorobjekt und gibt es zurück.Map
Konstruktor verwendet dieses Iteratorobjekt, um die Einträge (die[name, value]
Arrays) abzurufen und die Karte zu erstellenVerwenden des Generators:
Map
Konstruktor ruft eine Funktion für dieses Generatorobjekt auf, um einen Iterator daraus abzurufen. Das Generatorobjekt gibt sich selbst zurückMap
Konstruktor verwendet das Generatorobjekt (als Iterator), um die Einträge (die[name, value]
Arrays) abzurufen und die Karte zu erstellenAlso: Ein Vermittler weniger (das Array von
Object.entries
).Die Verwendung
Object.entries
ist jedoch einfacher und das Erstellen dieses Arrays ist in 99,999% der Fälle kein Problem. Also wirklich, einer von beiden. Aber sie sind beide besser als die folgenden. :-)Ursprüngliche Antwort:
Zum Initialisieren von a
Map
können Sie einen beliebigen Iterator verwenden, der Schlüssel / Wert-Paare als Arrays zurückgibt, z. B. ein Array von Arrays:Es gibt keine integrierte Konvertierung von Objekt zu Karte, aber es ist einfach mit
Object.keys
:Sie können sich natürlich eine Arbeiterfunktion geben, um das zu erledigen:
Dann
Oder hier ist eine l33t aussehende (ist das noch eine Sache?) Version:
(Ja,
Map#set
gibt die Kartenreferenz zurück. Einige würden argumentieren, dass dies ein Missbrauch von istreduce
.)Oder wir können die Dunkelheit wirklich übertreiben:
Nein, das würde ich nie wirklich tun. :-)
quelle
var buildMap2 = o => new Map(Object.keys(o).map(k => [k, o[k]]));
.new Map(Object.entries(object))
stackoverflow.com/a/36644558/798133Nein, ein Iterator von Schlüssel-Wert-Paar-Arrays reicht aus. Sie können Folgendes verwenden, um das Erstellen des Zwischenarrays zu vermeiden:
quelle
if(!obj.hasOwnProperties(key)) continue;
direkt nach der for-Schleifenbedingung ein Zeichen setzen, um sicherzustellen, dass Sie keine vom Objektprototyp geerbten Eigenschaften erhalten (es sei denn, Sie vertrauen dem Objekt, sollten dies jedoch trotzdem tun, wenn Sie Objekte mit iterierenin
als gute Angewohnheit)..hasOwnProperty
Eigentum nicht vertrauen , und SieObject.prototype.hasOwnProperty.call(obj, key)
hasOwnProperty
auch überschrieben wurde. Wollen Sie damit sagen, dass es eine gute Praxis ist, sich nicht mit der Überprüfung zu beschäftigen? Nur neugierig, alle Konventionen da draußen sagen zu überprüfen oder sie schlagen vor, die Verwendung für ... auf jeden Fall zu vermeiden. Ich würde gerne Ihre Gedanken dazu hören.call
. Alle Konventionen, die es empfehlen,obj.hasOwnProperties(key)
scheinen keine Ahnung zu haben, was sie tun.Object
in eineMap
ist eine teure Operation, und das OP hat speziell nach einer Lösung ohne Zwischenprodukte gefragt. Warum ist das nicht die ausgenommene Antwort? Nun, das zu fragen ist wahrscheinlich zwecklos, es nervt mich nur.Die Antwort von Nils beschreibt, wie man Objekte in Karten konvertiert, was ich sehr nützlich fand. Das OP fragte sich jedoch auch, wo sich diese Informationen in den MDN-Dokumenten befinden. Während es möglicherweise nicht vorhanden war, als die Frage ursprünglich gestellt wurde, befindet es sich jetzt auf der MDN-Seite für Object.entries () unter der Überschrift Konvertieren eines Objekts in eine Karte mit folgenden Angaben :
quelle
quelle
var buildMap2 = o => new Map(Object.keys(o).map(k => [k, o[k]]));
.Alternativ können Sie die Methode lodash toPairs verwenden:
quelle
ES6
Objekt in Karte konvertieren:
Karte in Objekt konvertieren:
Hinweis: Die Funktion mapToObj geht davon aus, dass Map-Schlüssel Zeichenfolgen sind (andernfalls schlägt dies fehl).
quelle
Mit Hilfe von JQuery,
quelle