Ich möchte einen JSON-Objektbaum durchlaufen, kann aber keine Bibliothek dafür finden. Es scheint nicht schwierig zu sein, aber es fühlt sich an, als würde man das Rad neu erfinden.
In XML gibt es so viele Tutorials, die zeigen, wie man einen XML-Baum mit DOM durchläuft :(
javascript
json
Patsy Issa
quelle
quelle
Antworten:
Wenn Sie der Meinung sind, dass jQuery für eine so primitive Aufgabe eine Art Overkill ist , können Sie so etwas tun:
quelle
this
Wert in der Zielfunktion, währendo
der erste Parameter für die Funktion sein sollte. Das Einstellen aufthis
(was dietraverse
Funktion wäre) ist zwar etwas seltsam, aber es ist sowieso nicht so,process
als würde man diethis
Referenz verwenden. Es hätte genauso gut null sein können./*jshint validthis: true */
oben hinzufügenfunc.apply(this,[i,o[i]]);
, um den Fehler zu vermeiden, derW040: Possible strict violation.
durch die Verwendung vonthis
traverse
Funktion einen 3-Parameter hinzufügen, der die Tiefe verfolgt. Wenn Sie rekursiv aufrufen, addieren Sie 1 zur aktuellen Ebene.Ein JSON-Objekt ist einfach ein Javascript-Objekt. Dafür steht JSON eigentlich: JavaScript Object Notation. Sie würden also ein JSON-Objekt durchlaufen, jedoch ein Javascript-Objekt im Allgemeinen "durchlaufen".
In ES2017 würden Sie Folgendes tun:
Sie können jederzeit eine Funktion schreiben, um rekursiv in das Objekt abzusteigen:
Dies sollte ein guter Ausgangspunkt sein. Ich empfehle dringend, für solche Dinge moderne Javascript-Methoden zu verwenden, da sie das Schreiben von Code erheblich erleichtern.
quelle
function traverse(jsonObj) { if(jsonObj && typeof jsonObj == "object" ) { ...
quelle
much better
?!!o[i] && typeof o[i] == 'object'
Es gibt eine neue Bibliothek zum Durchlaufen von JSON-Daten mit JavaScript, die viele verschiedene Anwendungsfälle unterstützt.
https://npmjs.org/package/traverse
https://github.com/substack/js-traverse
Es funktioniert mit allen Arten von JavaScript-Objekten. Es erkennt sogar Zyklen.
Es gibt auch den Pfad jedes Knotens an.
quelle
Kommt darauf an, was du machen willst. Hier ist ein Beispiel für das Durchlaufen eines JavaScript-Objektbaums, das Drucken von Schlüsseln und Werten währenddessen:
quelle
Wenn Sie eine tatsächliche JSON- Zeichenfolge durchlaufen , können Sie eine Reviver-Funktion verwenden.
Beim Durchqueren eines Objekts:
quelle
BEARBEITEN : Alle folgenden Beispiele in dieser Antwort wurden so bearbeitet, dass sie eine neue Pfadvariable enthalten, die vom Iterator gemäß der Anforderung von @ supersan ausgegeben wird . Die Pfadvariable ist ein Array von Zeichenfolgen, wobei jede Zeichenfolge im Array jeden Schlüssel darstellt, auf den zugegriffen wurde, um zum resultierenden iterierten Wert aus dem ursprünglichen Quellobjekt zu gelangen. Die Pfadvariable kann in die get-Funktion / -Methode von lodash eingespeist werden . Oder Sie könnten Ihre eigene Version von lodashs get schreiben, die nur Arrays wie folgt verarbeitet:
BEARBEITEN : Diese bearbeitete Antwort löst Endlosschleifen-Durchquerungen.
Stoppen von lästigen unendlichen Objektdurchquerungen
Diese bearbeitete Antwort bietet immer noch einen der zusätzlichen Vorteile meiner ursprünglichen Antwort, mit der Sie die bereitgestellte Generatorfunktion verwenden können, um eine sauberere und einfach iterierbare Schnittstelle zu verwenden (denken Sie an die Verwendung von
for of
Schleifen, beifor(var a of b)
denenb
es sich um eine iterierbare unda
ein Element der iterierbaren handelt ). Durch die Verwendung hilft es auch , mit Wiederverwendung von Code die Generatorfunktion zusammen mit einer einfacheren api zu sein , indem sie es machen , so dass Sie müssen nicht die Iterationslogik wiederholen überall Sie Iterierte wollen tief auf die Eigenschaften eines Objekts und macht es auch möglich , siebreak
aus die Schleife, wenn Sie die Iteration früher stoppen möchten.Eine Sache, die mir auffällt und die nicht in meiner ursprünglichen Antwort enthalten ist, ist, dass Sie vorsichtig beliebige (dh "zufällige") Objekte durchlaufen sollten, da JavaScript-Objekte selbstreferenzierend sein können. Dies schafft die Möglichkeit, Endlosschleifen-Durchquerungen durchzuführen. Nicht geänderte JSON-Daten können sich jedoch nicht selbst referenzieren. Wenn Sie also diese bestimmte Teilmenge von JS-Objekten verwenden, müssen Sie sich keine Gedanken über Endlosschleifen-Durchläufe machen, und Sie können auf meine ursprüngliche Antwort oder andere Antworten verweisen. Hier ist ein Beispiel für eine nicht endende Durchquerung (beachten Sie, dass es sich nicht um einen ausführbaren Code handelt, da sonst die Registerkarte Ihres Browsers abstürzen würde).
Auch im Generatorobjekt in meinem bearbeiteten Beispiel habe ich mich für die Verwendung entschieden,
Object.keys
anstattfor in
nur Nicht-Prototyp-Schlüssel für das Objekt zu iterieren. Sie können dies selbst austauschen, wenn Sie die Prototypschlüssel enthalten möchten. Siehe meinen ursprünglichen Antwortabschnitt unten für beide Implementierungen mitObject.keys
undfor in
.Schlimmer - Dies führt zu einer Endlosschleife für selbstreferenzielle Objekte:
Um sich davor zu schützen, können Sie einen Satz innerhalb eines Abschlusses hinzufügen, sodass die Funktion beim ersten Aufruf beginnt, einen Speicher für die Objekte zu erstellen, die sie gesehen hat, und die Iteration nicht fortsetzt, sobald sie auf ein bereits gesehenes Objekt stößt. Das folgende Code-Snippet macht das und behandelt somit Endlosschleifenfälle.
Besser - Dies führt nicht zu einer Endlosschleife für selbstreferenzielle Objekte:
Ursprüngliche Antwort
Eine neuere Möglichkeit, dies zu tun, wenn es Ihnen nichts ausmacht, den IE zu löschen und hauptsächlich aktuellere Browser zu unterstützen (überprüfen Sie die es6-Tabelle von kangax auf Kompatibilität). Hierfür können Sie es2015- Generatoren verwenden . Ich habe die Antwort von @ TheHippo entsprechend aktualisiert. Wenn Sie wirklich IE-Unterstützung wünschen, können Sie natürlich den babel JavaScript-Transpiler verwenden.
Wenn Sie nur eigene aufzählbare Eigenschaften wünschen (im Grunde keine Eigenschaften einer Prototypkette), können Sie diese so ändern, dass sie stattdessen mit
Object.keys
und einerfor...of
Schleife iteriert werden :quelle
Ich wollte die perfekte Lösung von @TheHippo in einer anonymen Funktion verwenden, ohne Prozess- und Triggerfunktionen zu verwenden. Das Folgende hat für mich funktioniert und für unerfahrene Programmierer wie mich geteilt.
quelle
Die meisten Javascript-Engines optimieren die Schwanzrekursion nicht (dies ist möglicherweise kein Problem, wenn Ihr JSON nicht tief verschachtelt ist), aber ich bin normalerweise vorsichtig und mache stattdessen eine Iteration, z
quelle
Mein Skript:
Eingabe JSON:
Funktionsaufruf:
Ausgabe gemäß meinem Bedarf:
quelle
quelle
Die beste Lösung für mich war die folgende:
einfach und ohne Verwendung eines Frameworks
quelle
Sie können alle Schlüssel / Werte abrufen und damit die Hierarchie beibehalten
Dies ist eine Änderung am ( https://stackoverflow.com/a/25063574/1484447 )
quelle
quelle
Ich habe eine Bibliothek erstellt, um tief verschachtelte JS-Objekte zu durchlaufen und zu bearbeiten. Überprüfen Sie die API hier: https://github.com/dominik791
Sie können auch interaktiv mit der Bibliothek spielen, indem Sie die Demo-App verwenden: https://dominik791.github.io/obj-traverse-demo/
Anwendungsbeispiele: Sie sollten immer ein Root-Objekt haben, das der erste Parameter jeder Methode ist:
Der zweite Parameter ist immer der Name der Eigenschaft, die verschachtelte Objekte enthält. Im obigen Fall wäre es
'children'
.Der dritte Parameter ist ein Objekt, mit dem Sie Objekte finden, die Sie suchen / ändern / löschen möchten. Wenn Sie beispielsweise nach einem Objekt mit einer ID von 1 suchen, übergeben Sie es
{ id: 1}
als dritten Parameter.Und du kannst:
findFirst(rootObj, 'children', { id: 1 })
erstes Objekt finden mitid === 1
findAll(rootObj, 'children', { id: 1 })
um alle Objekte mit zu findenid === 1
findAndDeleteFirst(rootObj, 'children', { id: 1 })
um das erste übereinstimmende Objekt zu löschenfindAndDeleteAll(rootObj, 'children', { id: 1 })
um alle übereinstimmenden Objekte zu löschenreplacementObj
wird als letzter Parameter in zwei letzten Methoden verwendet:findAndModifyFirst(rootObj, 'children', { id: 1 }, { id: 2, name: 'newObj'})
um das zuerst gefundene Objekt mitid === 1
dem zu ändern{ id: 2, name: 'newObj'}
findAndModifyAll(rootObj, 'children', { id: 1 }, { id: 2, name: 'newObj'})
um alle Objekte mitid === 1
dem zu ändern{ id: 2, name: 'newObj'}
quelle