Itérer Imbriqués les Objets JavaScript
Je suis en train de parcourir un objet imbriqué pour récupérer un objet spécifique identifié par une chaîne de caractères. Dans l'échantillon de l'objet ci-dessous, la chaîne de l'identificateur est le "label" de la propriété. Je ne peut pas envelopper la tête autour de comment itérer à travers l'arbre de retourner l'objet approprié. Toute aide ou suggestion serait grandement apprécié.
var cars = {
label: 'Autos',
subs: [
{
label: 'SUVs',
subs: []
},
{
label: 'Trucks',
subs: [
{
label: '2 Wheel Drive',
subs: []
},
{
label: '4 Wheel Drive',
subs: [
{
label: 'Ford',
subs: []
},
{
label: 'Chevrolet',
subs: []
}
]
}
]
},
{
label: 'Sedan',
subs: []
}
]
}
- double possible de Parcourir tous les Nœuds d'un Objet JSON Arbre avec JavaScript
- Vous êtes désireux de recherche à travers tous les niveaux de l'objet de l'arbitraire d'un label? (Aha, le traverse, c'est le mot que je cherchais.)
- Double Possible de Accès / processus (imbriqué) des objets, des tableaux ou JSON
- Double Possible de Parcourir tous les Nœuds d'un Objet JSON Arbre avec JavaScript
Vous devez vous connecter pour publier un commentaire.
Vous pouvez créer une fonction récursive comme ça pour faire une profondeur d'abord la traversée de la
cars
objet.qui peut être appelé comme
subs
tableau.subs
à autre chose.obj.hasOwnProperty(i)
, personnalisé propriétés du prototype seront inclus. Par exemple, si vous définissezArray.prototype.first = function(a) { return a[0] }
, puisfor(var i in [])
comprendra la propriété prototype defirst
.Dans le cas où vous souhaitez profondément itérer dans un complexe (imbriqué) de l'objet pour chaque clé & valeur, vous pouvez le faire en utilisant Objet.les touches(), de manière récursive:
REPL exemple.
Le code suivant n'assume aucune références circulaires, et n'assume
subs
est toujours un tableau (et non pas la valeur null dans les nœuds feuilles):Ici est un mort-méthode simple en utilisant seulement 3 variables, à seulement 9 lignes de code, et pas de récursivité.
D'utiliser la fonction ci-dessus, passer le tableau en tant que premier argument et la fonction de rappel comme deuxième argument. La fonction de rappel recevront 1 argument quand on l'appelle: l'élément actuel itérée.
JS:
Un "cheat" autre solution pourrait être d'utiliser
JSON.stringify
à itérer. CEPENDANT,JSON.stringify
fera appel à latoString
méthode de chaque objet, il passe au-dessus, ce qui peut produire des résultats inattendus si vous avez votre propre usages spéciaux pour latoString
.JS:
Cependant, alors que la méthode ci-dessus peut être utile pour les besoins de la démonstration,
Object.values
n'est pas pris en charge par Internet Explorer et il y a beaucoup de terriblement illperformant endroits dans le code:Array.prototype.push
etArray.prototype.pop
sur chaque article unique [5 lignes & 8],Object.values
[ligne 8],window.Object
ouwindow.Object.values
[9],Ci-dessous est beaucoup beaucoup plus rapide version qui devrait être bien plus rapide que toute autre solution. La solution ci-dessous résout tous les problèmes de performance énumérés ci-dessus. Cependant, il parcourt de façon bien différente: il parcourt tous les tableaux premier, puis parcourt tous les objets. Il continue à itérer ses actuels jusqu'à l'épuisement complet, y compris itération subvalues à l'intérieur de la liste actuelle de l'actuel saveur itérée. Ensuite, la fonction itérée tous de l'autre type. Par itération jusqu'à épuisement avant de basculer, la boucle d'itération devient plus chaud que l'autre et parcourt encore plus vite. Cette méthode est également livré avec un avantage supplémentaire: le callback qui est appelée à chaque valeur est passée d'un deuxième paramètre. Ce second paramètre est le tableau retourné par
Object.values
appelée sur le parent de hachage de l'Objet ou de la mère Tableau lui-même.JS:
Si vous avez un problème avec les références circulaires (par exemple Un objet de valeurs d'Un objet lui-même dans tel que celui de l'objet A contient lui-même), ou vous avez juste besoin les clés puis de la après un ralentissement de la solution est disponible.
Car ces méthodes ne pas utiliser la récursivité de toute sorte, ces fonctions sont bien adaptés pour les zones où vous risquez d'avoir des milliers de niveaux de profondeur. La limite d'empilement varie considérablement d'un navigateur à l'autre, de sorte que la récursivité à une profondeur inconnue n'est pas très sage en Javascript.
Pour augmenter les performances pour plus d'arbre de la manipulation est bon de transformer la vue de l'arborescence en ligne de collecte de vue, comme [obj1, obj2, obj3]. Vous pouvez stocker parent-enfant, relations d'objet facile à naviguer pour parent/enfant.
À la recherche de l'élément à l'intérieur de la collection est plus efficace puis de trouver l'élément à l'intérieur de l'arbre (récursivité, plus dynamique, une fonction de création, de fermeture).
modifier à partir de Peter Olson's réponse: https://stackoverflow.com/a/8085118
!obj || (typeof obj === 'string'
L'extrait de code suivant va se répéter sur les objets imbriqués. Les objets à l'intérieur des objets. Se sentir libre de le modifier pour répondre à vos exigences. Si vous souhaitez ajouter une matrice de soutien if-else et faire une fonction qui boucle par le biais de réseaux ...
JS:
Vous pouvez obtenir par le biais de chaque objet de la liste et d'obtenir la valeur que vous souhaitez. Il suffit de passer un objet en tant que premier paramètre de l'appel de la fonction et de la propriété de l'objet qui vous voulez comme deuxième paramètre. Changement de l'objet avec votre objet.
JS:
Ici est une description concise de l'ampleur-la première solution itérative, que je préfère à la récursivité:
Vous pouvez avoir une fonction récursive avec une fonction d'analyse construit à l'intérieur d'elle.
Voici comment cela fonctionne
JS:
J'ai fait une méthode de sélection comme lodash choisir. Il n'est pas vraiment bon, comme lodash _.de sélection, mais vous pouvez choisir n'importe quelle propriété de l'événement tout imbriqué de la propriété.
par exemple:
Code :
et voici le lien direct exemple avec les tests unitaires