TypeScript, Durchlaufen eines Wörterbuchs

184

In meinem Code habe ich ein paar Wörterbücher (wie hier vorgeschlagen ), die String-indiziert sind. Da es sich um einen improvisierten Typ handelt, habe ich mich gefragt, ob es Vorschläge gibt, wie ich die einzelnen Schlüssel (oder Werte, für die ich die Schlüssel sowieso brauche) durchlaufen kann. Jede Hilfe geschätzt!

myDictionary: { [index: string]: any; } = {};
ben657
quelle
Hast du versucht : for (var key in myDictionary) { }? Innerhalb der Schleife würden Sie verwenden key, um den Schlüssel und myDictionary[key]den Wert zu erhalten
Ian
@ Ian Ich habe es gerade versucht, scheint nicht zu funktionieren. Keine Fehler, aber nichts läuft innerhalb der Anweisung
ben657
1
@ Ian Ah sorry, irgendein Code anderswo hat damit rumgespielt. Das funktioniert perfekt! Möchtest du eine Antwort geben, damit ich sie auswählen kann?
Ben657

Antworten:

294

Verwenden Sie eine for inSchleife, um die Schlüssel / Werte zu durchlaufen:

for (let key in myDictionary) {
    let value = myDictionary[key];
    // Use `key` and `value`
}
Ian
quelle
8
Dies ist im Allgemeinen nicht sicher. Es benötigt den hasOwnProperty-Test (wie in Jamie Starks Antwort) oder etwas anderes.
Don Hatch
20
@ DonHatch Es ist eigentlich sehr sicher im Allgemeinen. Dies ist in ganz bestimmten Fällen nicht sicher (z. B. wenn Sie Bibliotheken einschließen, die Prototypen falsch oder absichtlich falsch ändern). Es ist Sache des Entwicklers, seinen Code mit höchstwahrscheinlich unnötigen Überprüfungen aufzublähen
Ian,
1
@Ian - Ich denke, ich würde es nicht ohne zusätzliche Sicherheitsvorkehrungen verwenden, da es wie ein Unfall aussieht, der darauf wartet, passiert zu werden, z. B. wenn der Code seinen Weg in eine Dienstprogrammfunktion findet und dann jemand dieser Funktion ein Wörterbuch übergibt, das nicht einfach ein ist Objekt, sondern etwas mit zusätzlichen Eigenschaften. Ja, wie Sie sagen, liegt es am Entwickler, die Wahrscheinlichkeit und den Schweregrad eines solchen Szenarios abzuwägen. Für mich besteht der am wenigsten geistig belastende Ansatz darin, sich so zu verhalten, als ob ein solches Szenario in allen Fällen garantiert ist - weniger zum Nachdenken.
Don Hatch
5
@ Ian Das Problem ist, dass es zu viele Bibliotheken gibt, die Objektprototypen ändern. Es scheint eine schlechte Idee zu sein, diese Art von Muster zu befürworten, wenn es viel bessere einfache Alternativen gibt, wie z Object.keys(target).forEach(key => { let value = target(key); /* Use key, value here */ });. Wenn Sie diese Methode zeigen müssen, erwähnen Sie zumindest die Risiken und besseren Alternativen für diejenigen, die es noch nicht besser wissen.
Yona Appletree
8
Wir haben bereits es6 und TypeScript. Warum bleibt das Problem, hasOwnProperty ständig zu schreiben, ungelöst? Auch im Jahr 2017 und mit aller Aufmerksamkeit auf JS. Ich bin so enttäuscht.
Gherman
168

<ES 2017 :

Object.keys(obj).forEach(key => {
  let value = obj[key];
});

> = ES 2017 :

Object.entries(obj).forEach(
  ([key, value]) => console.log(key, value);
);
Stephen Paul
quelle
Dies ist die Lösung, nach der ich gesucht habe, da ich die Schlüssel vor der Iteration sortieren kann
Andrew,
Zu Ihrer Information, dies wird derzeit auf dem TypeScript-Spielplatz nicht unterstützt.
Seanny123
1
Sehen Sie hier, wie man Object.entriesin TypeScript arbeitet
Alex Klaus
Das ist perfekt
Piyush Choudhary
66

Wie wäre es damit?

for (let [key, value] of Object.entries(obj)) {
    ...
}
Radon Rosborough
quelle
1
Es erfordert lib es2017 in tsconfig. Siehe stackoverflow.com/questions/45422573/…
Stéphane
Dies ist, was ich brauchte, um den Typescript-Fehler auf obj [Schlüssel] "Keine Indexsignatur ..." zu überwinden, da ich meinen obj-Typ explizit als {[Schlüssel: Zeichenfolge]: Zeichenfolge} festgelegt habe und nicht {[Schlüssel: Zeichenfolge]: any}. Damit kann ich einfach auf 'Wert' zugreifen. Danke
ggedde
Und wenn Sie überhaupt ignorieren möchten key, lassen Sie es einfach leer : [ , value]. (Dank dieses Problemkommentars .)
Dominik
50

Die von Ian erwähnte Schlüssel- / Werteschleife enthält eine Einschränkung. Wenn es möglich ist, dass den Objekten Attribute zugeordnet sind, und wenn Sie den inOperator verwenden, werden diese Attribute eingeschlossen. Sie sollten also sicherstellen, dass der Schlüssel ein Attribut Ihrer Instanz und nicht des Prototyps ist. Ältere IEs sind dafür bekannt, dass indexof(v)sie als Schlüssel auftauchen.

for (const key in myDictionary) {
    if (myDictionary.hasOwnProperty(key)) {
        let value = myDictionary[key];
    }
}
Jamie Starke
quelle
2
Versuchen Sie nicht, Haare zu spalten, aber da es sich um ein Typenskript handelt, sollten Sie nicht let key anstelle von var key verwenden? Schöne Antwort, danke.
Luke Dupin
3
In der Tat kann mit der aktuellen Version des Typenskripts das keyund valuesein const.
Patrick Desjardins
Es ist besser, die hasOwnPropertyPrüfung nicht vom Zielobjekt aus aufzurufen , sondern ...if (Object.prototype.hasOwnProperty.call(myDictionary, key))...Folgendes : Wenn Sie eslint mit no-prototype-builtinsRegel verwenden, wird ein Fehler ausgegeben .
Sceee
5

Kürzester Weg, um alle Wörterbuch- / Objektwerte zu erhalten:

Object.keys(dict).map(k => dict[k]);
k06a
quelle
0

So erhalten Sie die Schlüssel:

function GetDictionaryKeysAsArray(dict: {[key: string]: string;}): string[] {
  let result: string[] = [];
  Object.keys(dict).map((key) =>
    result.push(key),
  );
  return result;
}
Ribeiro
quelle
0

Ians Antwort ist gut, aber Sie sollten const anstelle von let für den Schlüssel verwenden, da er nie aktualisiert wird.

for (const key in myDictionary) {
    let value = myDictionary[key];
    // Use `key` and `value`
}
finnk
quelle