Comment puis-je accéder et de processus imbriqués objets, des tableaux ou JSON?
J'ai un imbriquée structure de données contenant les objets et les tableaux. Comment puis-je extraire les informations, c'est à dire l'accès spécifique ou plusieurs valeurs (ou clés)?
Par exemple:
var data = {
code: 42,
items: [{
id: 1,
name: 'foo'
}, {
id: 2,
name: 'bar'
}]
};
Comment pourrais-je accéder à la name
du second élément items
?
- Il doit être lu ainsi: "j'ai une de données imbriquées structure de données ou JSON, comment puis-je accéder à une valeur spécifique?". Je sais faire la différence, mais beaucoup de gens ne le font pas et peut-être de la recherche pour "JSON" plutôt que de "l'objet". De nombreuses questions sont en fait de la forme "comment puis-je accéder à X dans ce JSON". Le seul endroit où je mentionne JSON dans ma réponse est où j'explique ce que c'est. Si vous avez une suggestion comment communiquer dans une meilleure façon, je suis toutes les oreilles.
- double possible de JSON trouver en JavaScript
Vous devez vous connecter pour publier un commentaire.
Préliminaires
JavaScript n'a qu'un seul type de données qui peut contenir plusieurs valeurs: Objet. Un Tableau est une forme particulière de l'objet.
(Plaine) les Objets ont la forme
Tableaux ont la forme
Les deux tableaux et objets d'exposer un
key -> value
structure. Clés dans un tableau doit être numérique, alors que n'importe quelle chaîne peut être utilisé comme clé dans les objets. Les paires clé-valeur sont aussi appelés les "propriétés".Propriétés peuvent être accessibles soit à l'aide de point notation
ou support de la notation, si le nom de la propriété ne serait pas valide JavaScript nom de l'identificateur [spec], ou le nom est la valeur d'une variable:
Pour cette raison, les éléments du tableau ne peut être consulté à l'aide de support de la notation:
Attendre... qu'en JSON?
JSON est une représentation textuelle des données, tout comme XML, YAML, CSV, et d'autres. Pour travailler avec ces données, il doit être converti en JavaScript types de données, c'est à dire des tableaux et des objets (et comment travailler avec celles-ci, vient de l'expliquer). Comment analyser le JSON est expliqué dans la question Parser JSON en JavaScript? .
Plus du matériel de lecture
Comment accéder à des tableaux et des objets est fondamental JavaScript connaissances et, par conséquent, il est conseillé de lire les MDN JavaScript Guide, en particulier les sections
Accéder aux structures de données imbriquées
Imbriquée structure de données est un tableau ou un objet qui renvoie à d'autres tableaux ou des objets, c'est à dire ses valeurs sont des tableaux ou des objets. De telles structures peuvent être consultées par consécutivement à l'application de dot ou de support de la notation.
Voici un exemple:
Supposons que nous voulons accéder à la
name
du deuxième élément.Ici est de savoir comment nous pouvons le faire étape par étape:
Comme nous pouvons le voir
data
est un objet, par conséquent, nous pouvons accéder à ses propriétés à l'aide de la notation point. Leitems
de la propriété est accessible comme suit:La valeur est un tableau, pour accéder à sa deuxième élément, il faut utiliser la notation crochets:
Cette valeur est un objet, et nous utilisons la notation point de nouveau pour accéder à la
name
de la propriété. Donc, nous avons fini par obtenir:Sinon, on aurait pu se servir de support de la notation pour les propriétés, en particulier si le nom figurant des personnages qui auraient rendu invalide pour la notation de point d'utilisation:
J'essaye d'accéder à une propriété, mais je ne reçois que
undefined
dos?La plupart du temps lorsque vous êtes
undefined
, l'objet ou le tableau n'est pas simplement une propriété de même nom.Utilisation
de la console.log
oude la console.dir
et inspecter la structure de l'objet /tableau. La propriété que vous essayez d'accès peut être réellement définie sur un objet imbriqué /tableau.Que si les noms de propriété sont dynamiques et je ne les connais pas à l'avance?
Si les noms des propriétés sont inconnues ou nous voulons accéder à toutes les propriétés d'un objet /d'éléments d'un tableau, nous pouvons utiliser la
for...in
[MDN] boucle pour les objets et lesfor
[MDN] boucle pour les tableaux d'itérer sur toutes les propriétés des éléments.Objets
Pour itérer sur toutes les propriétés de
data
, nous pouvons itérer sur les objet comme suit:Selon l'endroit où l'objet vient (et ce que vous voulez faire), vous pourriez avoir à tester à chaque itération si la propriété est vraiment une propriété de l'objet, ou c'est une propriété héritée. Vous pouvez faire cela avec
Objet#hasOwnProperty
[MDN].Comme alternative à
for...in
avechasOwnProperty
, vous pouvez utiliserde l'Objet.les touches
[MDN] pour obtenir un tableau des noms de propriété:Tableaux
Pour itérer sur tous les éléments de la
data.items
tableau, nous utilisons unfor
boucle:On peut aussi utiliser
for...in
pour itérer sur tous les tableaux, mais il ya des raisons pourquoi cela devrait être évité: Pourquoi est - 'for(var item dans la liste) avec des tableaux considéré comme une mauvaise pratique en JavaScript?.Avec l'augmentation de la prise en charge du navigateur ECMAScript 5, la méthode de la baie
forEach
[MDN] devient une alternative intéressante ainsi:Dans des environnements de soutien ES2015 (ES6), vous pouvez également utiliser le
pour...de
[MDN] boucle, qui ne travaille pas seulement pour les tableaux, mais pour tout objet iterable:À chaque itération,
for...of
directement nous donne l'élément suivant de la itératif, il n'y a pas de "index" pour l'accès ou de l'utilisation.Que si la "profondeur" de la structure de données est inconnu pour moi?
En plus des inconnus clés, de la "profondeur" de la structure de données (c'est à dire combien d'objets imbriqués), il a, peut-être inconnu ainsi. Comment accéder profondément imbriqués propriétés dépend de la précision de la structure de données.
Mais si la structure de données contient des schémas répétitifs, par exemple, la représentation d'un arbre binaire, la solution comprend généralement à de manière récursive [Wikipedia] accéder à chaque niveau de la structure de données.
Voici un exemple pour obtenir le premier nœud feuille d'un arbre binaire:
JS:
Plus générique pour accéder à une imbriqués structure de données avec des inconnus clés et la profondeur est de tester le type de la valeur et d'agir en conséquence.
Voici un exemple qui ajoute les valeurs primitives à l'intérieur d'un ensemble de structure de données dans un tableau (en supposant qu'il ne contient pas toutes les fonctions). Si nous rencontrons un objet (ou un tableau), nous appelons simplement
toArray
de nouveau sur cette valeur (appel récursif).JS:
Aides
Puisque la structure d'un objet complexe ou un tableau n'est pas forcément évident, nous pouvons inspecter la valeur à chaque étape, afin de décider comment aller plus loin.
de la console.log
[MDN] etde la console.dir
[MDN] nous aider à faire cela. Par exemple (sortie de la console Chromée):Ici, nous voyons que
data.items
est un tableau à deux éléments qui sont à la fois des objets. Dans google Chrome, console les objets peuvent même être étendu et inspectés immédiatement.Cela nous dit que
data.items[1]
est un objet, et après l'expansion, nous voyons qu'elle a trois propriétés,id
,name
et__proto__
. Ce dernier est une propriété interne utilisé pour la chaîne de prototype de l'objet. Le prototype de la chaîne et de l'héritage est hors de portée pour cette réponse, cependant.let object = {a: 1, b: 2, c: { a: 3, b: 4 }};
, cette fonction retourne un tableau contenant un tableau pour chaque objet imbriqué, dans ce cas[ 1, 2, [ 3, 4 ] ]
Ne serait-il pas mieux d'utiliser concat dans l'appel récursif au lieu de pousser ? (exigeant un résultat à mutable)Vous pouvez y accéder de cette façon
ou
Les deux façons sont égaux.
Dans le cas où vous essayez d'accéder à un
item
à partir de l'exemple de la structure parid
ouname
, sans le savoir, la position dans le tableau, la meilleure façon de le faire serait d'utiliser underscore.js bibliothèque:De mon expérience, à l'aide des fonctions d'ordre supérieur, au lieu de
for
oufor..in
boucles résultats dans le code qui est plus facile à comprendre, et donc plus facile à gérer.Juste mes 2 cents.
À la fois, l'accès à un objet imbriqué à l'aide d'une chaîne de caractères peut être souhaitable. L'approche la plus simple est le premier niveau, par exemple
Mais ce n'est pas souvent le cas avec les complexes json. Comme json devient de plus en plus complexe, les approches permettant de trouver les valeurs à l'intérieur de l'json aussi devenue plus complexe. Une approche récursive pour naviguer dans le json est le meilleur, et de la façon que la récursivité est l'effet de levier dépend du type de données recherchées. Si il y a des instructions conditionnelles en cause, une json de recherche peut être un bon outil à utiliser.
Si la propriété en cours d'accès est déjà connu, mais le chemin est complexe, par exemple dans cet objet
Et vous savez que vous voulez obtenir le premier résultat de la matrice dans l'objet, peut-être que vous souhaitez utiliser
Cependant, qui va provoquer une exception, car il n'y a pas de propriété de l'objet avec ce nom. La solution pour être en mesure d'utiliser ce serait pour aplatir l'arbre aspect de l'objet. Cela peut être fait de manière récursive.
Maintenant, l'objet complexe peut être aplatie
Ici est un
jsFiddle Démo
de cette approche utilisée.obj["arr[0].name"]
au lieu deobj.arr[0].name
? Vous avez à peine besoin/voulez traiter avec la objets aplatis sauf pour la sérialisation.Les objets et les tableaux a beaucoup de méthodes qui peuvent vous aider avec le traitement des données.
Remarque: dans la plupart des exemples que je suis en utilisant flèche fonctions. Ils sont semblables à les expressions de fonction, mais ils se lient les
this
valeur lexicalement.de l'Objet.les touches()
,de l'Objet.les valeurs de()
(ES 2017) etde l'Objet.entrées()
(ES 2017)Object.keys()
retourne un tableau d'objets clés, lesObject.values()
retourne un tableau d'objets de valeurs, etObject.entries()
retourne un tableau d'objet avec les touches et les valeurs correspondantes dans un format[key, value]
.JS:
Object.entries()
avec une boucle, et de la déstructuration d'affectationJS:
C'est très pratique pour itérer le résultat de
Object.entries()
avec un pour-de la boucle et déstructuration de cession.Pour de boucle permet d'itérer les éléments du tableau. La syntaxe est
for (const element of array)
(on peut remplacerconst
avecvar
oulet
, mais il est préférable d'utiliserconst
si nous n'avons pas l'intention de modifierelement
).Déstructuration d'affectation permet d'extraire des valeurs d'un tableau ou d'un objet et de les affecter à des variables. Dans ce cas
const [key, value]
signifie qu'au lieu d'attribuer la[key, value]
tableau deelement
, nous assignons le premier élément de ce tableau àkey
et le deuxième élément devalue
. Il est équivalent à ceci:Comme vous pouvez le voir, déstructuration qui rend ce beaucoup plus simple.
Array.le prototype.tous les()
etArray.le prototype.certains()
La
every()
méthode renvoietrue
si la fonction de callback retournetrue
pour chaque élément du tableau. Lesome()
méthode renvoietrue
si la fonction de callback retournetrue
pour certains (au moins un) élément.JS:
Array.le prototype.find()
etArray.le prototype.filtre()
La
find()
méthodes retourne la première élément qui répond à la fonction de rappel fourni. Lefilter()
méthode renvoie un tableau de tous éléments qui remplit la fonction de rappel fourni.JS:
Array.le prototype.map()
La
map()
méthode retourne un tableau avec les résultats de l'appel d'une fonction de rappel fourni sur les éléments du tableau.JS:
Array.le prototype.réduire()
La
reduce()
méthode permet de réduire un tableau à une seule valeur par l'appel de la fonction de rappel fourni avec deux éléments.JS:
La
reduce()
méthode prend un paramètre optionnel, qui est la valeur initiale. Ceci est utile lorsque le tableau sur lequel vous appelezreduce()
peut a zéro ou un des éléments. Par exemple, si nous avons voulu créer une fonctionsum()
qui prend un tableau en argument et retourne la somme de tous les éléments, nous pourrions l'écrire comme ça:JS:
Cette question est assez vieux, donc contemporaine de la mise à jour. Avec l'apparition de ES2015 il existe des alternatives à obtenir une prise de les données dont vous avez besoin. Il y a maintenant une fonctionnalité appelée objet déstructuration pour accéder à des objets imbriqués.
JS:
L'exemple ci-dessus crée une variable appelée
secondName
de laname
clé à partir d'un tableau appeléitems
, le solitaire,
dit ignorer le premier objet dans le tableau.En particulier, il est probablement excessif pour cet exemple, comme un simple tableau de l'accès est plus facile à lire, mais il est utile lors de briser des objets en général.
C'est très brève introduction à votre cas d'utilisation spécifiques, déstructuration peut être un peu de syntaxe pour obtenir utilisé pour la première fois. Je vous recommande la lecture de Mozilla Déstructuration d'Attribution de la documentation pour en savoir plus.
D'accéder à un ensemble d'attribut, vous devez spécifier son nom et la recherche par le biais de l'objet.
Si vous connaissez déjà le chemin d'accès exact, alors vous pouvez coder en dur dans le script comme ceci:
ces travaux -
Quand vous ne connaissez pas le nom exact avant de la main, ou un utilisateur est celui qui fournit le nom pour vous. Alors de façon dynamique à la recherche par le biais de la structure de données est nécessaire. Certains ont suggéré ici que la recherche peut être faite à l'aide d'un
for
boucle, mais il y a un moyen très simple de parcourir un chemin à l'aide deArray.réduire
.Le chemin d'accès est une façon de dire: d'Abord prendre l'objet avec les principaux
items
, qui se trouve être un tableau. Puis prendre la1
-st élément (0, l'index des tableaux). Dernier de prendre l'objet avec les principauxname
en ce que l'élément de tableau, qui se trouve être la chaînebar
.Si vous avez un chemin très long, vous pourriez même utiliser
String.split
pour rendre tout cela plus facile -C'est juste du pur JavaScript, sans l'aide d'un tiers des bibliothèques comme jQuery ou lodash.
À l'aide de JSONPath serait l'un des la plupart des solutions flexibles si vous êtes prêt à inclure dans une bibliothèque:
https://github.com/s3u/JSONPath (nœud et navigateur)
Pour votre cas d'utilisation, le json chemin d'accès serait:
donc:
Je préfère JQuery. C'est plus propre et facile à lire.
HTML:
Vous pouvez utiliser
lodash _get
fonction:ou
Fondamentalement, il faut utiliser un point entre chaque descendant qui se déroule en dessous, et quand vous avez des noms d'objet, formée de deux chaînes, vous devez utiliser l' ["obj Nom"] notation. Sinon, juste un point suffirait;
Source: https://learn.freecodecamp.org/javascript-algorithms-and-data-structures/basic-javascript/accessing-nested-objects
pour ajouter à cela, l'accès à des Tableaux imbriqués allait se passer comme ça:
Source: https://learn.freecodecamp.org/javascript-algorithms-and-data-structures/basic-javascript/accessing-nested-arrays/
Un autre document plus utile illustrant la situation ci-dessus:
https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Objects/Basics#Bracket_notation
Si vous êtes à la recherche d'un ou plusieurs objets qui satisfont à certains critères, vous avez quelques options, à l'aide de requête-js
Il y a aussi un
single
et unsingleOrDefault
ils travaillent beaucoup commefirst
etfirstOrDefault
respectivement. La seule différence est que ils vont jeter si plus qu'une correspondance est trouvée.pour de plus amples explications de la requête-js vous pouvez commencer avec cette post
Le trait de Soulignement js Façon
Qui est une bibliothèque JavaScript qui fournit un gâchis de utile
functional programming
aides sans augmenter tout les objets intégrés.Solution:
Une vieille question, mais comme personne n'a mentionné lodash (juste le trait de soulignement).
Dans le cas où vous êtes déjà à l'aide de lodash dans votre projet, je pense que c'est une manière élégante de le faire dans un complexe exemple:
Opt 1
même que:
Opt 2
La différence entre la première et la deuxième option est que, dans le Opt 1 si vous avez l'une des propriétés manquantes (non défini) dans le chemin d'accès que vous n'obtenez pas une erreur, il vous renvoie le troisième paramètre.
Pour la matrice de filtre lodash a
_.find()
mais je préfère l'utilisation de l'filter()
. Mais je pense toujours que la méthode ci-dessus_.get()
est super utile quand on travaille avec des données complexes. J'ai fait face dans le passé vraiment complexe Api et c'était pratique!J'espère que cela peut être utile pour qui est à la recherche pour les options de manipuler très complexes et les données que le titre implique.
Je ne pense pas que l'interlocuteur seulement se rapportent à un niveau de l'objet imbriqué, donc je vous présente la suite de démonstration pour montrer comment accéder au nœud de profondément imbriqués objet json. Bon, allons trouver le nœud avec l'id '5'.
JS:
HTML:
Accéder dynamiquement multi-niveaux de l'objet.
De travail violon: https://jsfiddle.net/andreitodorut/3mws3kjL/
Juste au cas où, de toute personne visitant cette question en 2017 ou plus tard, et à la recherche d'un facile à retenir, voici élaborer un billet de blog sur Accéder à des Objets Imbriqués dans JavaScript sans être dupés par
Impossible de lire la propriété 'foo' undefined erreur
1. Oliver Steele objet imbriqué modèle de l'accès
La méthode la plus simple et la plus propre est d'utiliser Oliver Steele objet imbriqué modèle de l'accès
Avec cette notation, vous ne serez jamais à court dans
Impossible de lire la propriété 'name' undefined.
- Vous essentiellement de vérifier si l'utilisateur existe, si non, vous devez créer un objet vide à la volée. De cette façon, le prochain niveau de la clé de toujours être accessible à partir d'un objet ou d'un objet vide, mais jamais à partir de l'indéfini.
2. L'Accès Des Objets Imbriqués À L'Aide Du Tableau De Réduire
Pour être en mesure d'accéder à des tableaux imbriqués, vous pouvez écrire votre propre tableau de réduire util.
Il est également un excellent type de manipulation minimale de la bibliothèque typés que signifie tout cela pour vous.
((user || {}).address || new Array(3))[1].name
...[1].bar
entraînerait une erreur si l'élément1
n'existait pas. Mais c'est aussi le cas pour....foo.bar
sifoo
n'existait pas. Vous avez pour "garder" l'accès1
ainsi, tout comme vous, "garde" de toute autre propriété de l'accès. Un tableau est un objet. Un "élément de tableau" est une propriété. Correctement appliqué, il serait(((user || {}).address || {})[1] || {}).name
.Un pythonic, récursive et approche fonctionnelle de démêler arbitraire JSON arbres:
où données est une liste python (analysée à partir d'un JSON chaîne de texte):
jQuery grep fonction permet de filtrer à travers un tableau:
JS:
HTML:
Mon
stringjson
est à venir à partir de fichier PHP, mais encore, j'indique ici dansvar
. Quand je prends mon json dansobj
il va rien montrer c'est pourquoi j'ai mis mon fichier json commevar obj=JSON.parse(stringjson);
ainsi, après que je reçois
message
obj et de montrer dans boîte d'alerte puis-je obtenirdata
qui est tableau json et les stocker dans une varibleArrObj
puis j'ai lu l'objet premier de ce tableau avec la valeur de la clé, comme ceArrObj[0].id
stringjson
n'est pas une chaîne.Ici est l'approche dynamique - votre "profond" de la clé est une chaîne
'items[1].name'
(vous pouvez utiliser la notation de tableau[i]
à tout niveau) - si la clé n'est pas valide alors undefined est de retour.JS:
À l'aide de lodash serait une bonne solution
Ex: