Parcourir tous les Nœuds d'un Objet JSON Arbre avec JavaScript
J'aimerais traverser un objet JSON arbre, mais ne peut pas trouver n'importe quelle bibliothèque pour que. Il ne semble pas difficile, mais il se sent comme à réinventer la roue.
En XML, il ya tellement de nombreux tutoriels montrant comment parcourir un arbre XML avec DOM 🙁
- Fait itérateur IIFE github.com/eltomjan/ETEhomeTools/blob/master/HTM_HTA/... il a prédéfinis (de base) DepthFirst & BreadthFirst prochaine et la capacité à se déplacer à l'intérieur structure JSON sans récursivité.
Vous devez vous connecter pour publier un commentaire.
Si vous pensez que jQuery est une sorte de overkill pour une primitive de la tâche, vous pourriez faire quelque chose comme ça:
typeof null == 'object'
est vrai.func.apply()
au lieu de simplementfunc()
?func.apply
. Toutefois, il a été un moment depuis que j'ai écrit ce court morceau de code.this
valeur dans la fonction cible, alors queo
doit être le premier paramètre de la fonction. Le paramètrethis
(ce qui serait letraverse
fonction) est un peu bizarre, mais ce n'est pas commeprocess
utilise lethis
de référence, de toute façon. Il pourrait tout aussi bien avoir été nulle./*jshint validthis: true */
ci-dessusfunc.apply(this,[i,o[i]]);
pour éviter l'erreurW040: Possible strict violation.
causés par l'utilisation dethis
hasOwnProperty
vérifier dans la boucle for.log
n'est pas une fonction. Je pense que tu veux direconsole.log(key + " : "+value)
.traverse
fonction qui suit la profondeur. Wenn appelant récursivement ajouter 1 au niveau actuel.JSON.stringify()
vos données?Un objet JSON est tout simplement un objet Javascript. C'est ce que JSON est synonyme de: JavaScript Object Notation. Donc, si vous voulez parcourir un objet JSON cependant vous choisissez de "traverse" un objet Javascript en général.
Dans ES2017 vous feriez:
Vous pouvez toujours écrire une fonction récursive de descendre dans l'objet:
Cela devrait être un bon point de départ. Je recommande fortement, en utilisant les méthodes javascript pour de telles choses, car ils font d'écrire un tel code beaucoup plus facile.
function traverse(jsonObj) { if(jsonObj && typeof jsonObj == "object" ) { ...
much better
?!!o[i] && typeof o[i] == 'object'
Il y a une nouvelle bibliothèque pour la traversée des données JSON avec JavaScript qui prend en charge plusieurs cas d'utilisation.
https://npmjs.org/package/traverse
https://github.com/substack/js-traverse
Il fonctionne avec toutes sortes d'objets JavaScript. Il détecte même les cycles.
Il fournit le chemin d'accès de chaque nœud, trop.
Dépend de ce que vous voulez faire. Voici un exemple de parcours d'un objet JavaScript arbre, l'impression des clés et des valeurs qu'elle va à l':
Si vous êtes traversant une réelle JSON chaîne ensuite, vous pouvez utiliser un rénovateur de la fonction.
Lors de la traversée d'un objet:
MODIFIER: Toutes les réponses ont été modifiées pour inclure une nouvelle variable de chemin d'accès donné à partir de l'itérateur comme par @supersan demande. La variable path est un tableau de chaînes de caractères où chaque chaîne dans le tableau représente chaque clé qui a été consulté pour obtenir de l'itération de la valeur de la source d'origine de l'objet. La variable de chemin d'accès peut être alimenté en lodash obtenir de la fonction/méthode. Ou vous pouvez écrire votre propre version de lodash s get qui ne gère que des tableaux comme suit:
JS:
MODIFIER: Cette édité réponse résout boucle infinie traversals.
Arrêt Satanés Infini Objet Traversals
Cette édité réponse fournit encore un des avantages ajoutés de ma réponse originale à cette question qui vous permet d'utiliser le générateur de fonction afin d'utiliser un nettoyant et simple itérable interface (pense à l'aide de
for of
boucles comme dansfor(var a of b)
oùb
est un objet iterable eta
est un élément de l'objet iterable). En utilisant le générateur de fonction est une api simple, il contribue également à la réutilisation du code en faisant en sorte que vous n'avez pas à répéter l'itération de la logique partout où vous voulez effectuer une itération profondément sur les propriétés d'un objet et il rend également possible pourbreak
sort de la boucle si vous souhaitez arrêter l'itération précédente.Une chose que j'ai remarqué qui n'a pas été abordé et qui n'est pas originale dans ma réponse est que vous devez être prudent de la traversée de l'arbitraire (c'est à dire un "hasard" ensemble d'objets, parce que les objets JavaScript peut être auto-référencement. Cela crée la possibilité d'avoir un infini en boucle traversals. Non modifiée de données JSON, cependant ne peut pas être auto-référencement, donc si vous utilisez ce sous-ensemble particulier des objets JS vous n'avez pas à vous soucier de boucle infinie traversals et vous pouvez vous référer à ma réponse originale à cette question ou d'autres réponses. Voici un exemple d'une non-fin de la traversée (remarque il n'est pas exécutable, morceau de code, parce que sinon, il serait de planter votre navigateur onglet).
Également dans l'objet du générateur dans mon édité exemple, j'ai opté pour l'utilisation de
Object.keys
au lieu defor in
qui parcourt seul non-prototype clés sur l'objet. Vous pouvez remplacer cela par vous-même si vous voulez le prototype clés inclus. Voir ma réponse ci-dessous pour les implémentations avecObject.keys
etfor in
.Pire Ce sera une boucle infinie sur l'auto-référentielle des objets:
Pour vous sauver de cela, vous pouvez ajouter un ensemble à l'intérieur d'une clôture, de sorte que lorsque la fonction est appelée en premier, il commence à construire une mémoire des objets qu'il a vu et ne continue pas d'itération, une fois qu'il vient dans un déjà vu l'objet. L'extrait de code ci-dessous ne que et gère ainsi une infinie cas de boucle.
Mieux Ce ne sera pas de boucle infinie sur l'auto-référentielle des objets:
JS:
Réponse Originale À Cette Question
Pour une nouvelle façon de le faire si vous n'avez pas l'esprit tomber IE et surtout supportant plus les navigateurs actuels (vérifier kangax de l'es6 table pour la compatibilité). Vous pouvez utiliser es2015 générateurs pour cela. J'ai mis à jour @TheHippo de répondre en conséquence. Bien sûr, si vous voulez vraiment IE support, vous pouvez utiliser le babel JavaScript transpiler.
JS:
Si vous voulez seulement propres propriétés énumérables (essentiellement non-prototype propriétés de la chaîne), vous pouvez le modifier pour effectuer une itération à l'aide de
de l'Objet.les touches
et unpour...de
boucle à la place:JS:
Je voulais utiliser la solution parfaite de @TheHippo dans une fonction anonyme, sans l'utilisation de processus et de fonctions de déclenchement. La suite travaillé pour moi, de partage pour les programmeurs débutants comme moi.
La plupart des moteurs Javascript ne pas optimiser la queue de la récursivité (ce ne serait pas un problème si votre JSON n'est pas profondément imbriqués), mais j'ai l'habitude de pécher par excès de prudence et ne itération au lieu de cela, par exemple,
Mon Script:
Entrée JSON:
Appel De La Fonction:
De sortie comme pour mon Besoin:
JS:
HTML:
La meilleure solution pour moi a été la suivante:
simple et sans l'aide de tout cadre
Vous pouvez obtenir toutes les clés /valeurs et préserver la hiérarchie avec cette
C'est une modification (https://stackoverflow.com/a/25063574/1484447)
J'ai créé la bibliothèque de parcourir et de modifier profondément imbriquée objets JS. Découvrez API ici: https://github.com/dominik791
Vous pouvez également jouer avec la bibliothèque interactive à l'aide de démo app:
https://dominik791.github.io/obj-traverse-demo/
Exemples d'utilisation:
Vous devriez toujours avoir à la racine de l'objet qui est le premier paramètre de chaque méthode:
Le deuxième paramètre est toujours le nom de la propriété qui contient des objets imbriqués. Dans le cas ci-dessus, il serait
'children'
.Le troisième paramètre est un objet que vous utilisez pour trouver l'objet/les objets que vous souhaitez rechercher/modifier/supprimer. Par exemple, si vous êtes à la recherche pour l'objet dont l'id est égal à 1, alors vous passerez
{ id: 1}
comme troisième paramètre.Et vous pouvez:
findFirst(rootObj, 'children', { id: 1 })
pour trouver l'objet premieravec
id === 1
findAll(rootObj, 'children', { id: 1 })
trouver tous les objetsavec
id === 1
findAndDeleteFirst(rootObj, 'children', { id: 1 })
à supprimer le premier objet correspondantfindAndDeleteAll(rootObj, 'children', { id: 1 })
pour supprimer tous les objets correspondantsreplacementObj
est utilisé comme dernier paramètre dans les deux dernières méthodes:findAndModifyFirst(rootObj, 'children', { id: 1 }, { id: 2, name: 'newObj'})
pour changer d'abord objet trouvé avecid === 1
à la{ id: 2, name: 'newObj'}
findAndModifyAll(rootObj, 'children', { id: 1 }, { id: 2, name: 'newObj'})
de modifier tous les objets avecid === 1
à la{ id: 2, name: 'newObj'}