J'ai une structure de données comme celle-ci:
var someObject = {
'part1' : {
'name': 'Part 1',
'size': '20',
'qty' : '50'
},
'part2' : {
'name': 'Part 2',
'size': '15',
'qty' : '60'
},
'part3' : [
{
'name': 'Part 3A',
'size': '10',
'qty' : '20'
}, {
'name': 'Part 3B',
'size': '5',
'qty' : '20'
}, {
'name': 'Part 3C',
'size': '7.5',
'qty' : '20'
}
]
};
Et je voudrais accéder aux données en utilisant ces variables:
var part1name = "part1.name";
var part2quantity = "part2.qty";
var part3name1 = "part3[0].name";
part1name doit être rempli avec someObject.part1.name
la valeur de, qui est "Part 1". Même chose avec part2quantity qui a rempli de 60.
Existe-t-il de toute façon pour y parvenir avec du javascript pur ou JQuery?
javascript
jquery
path
nested
Komaruloh
la source
la source
var part1name = someObject.part1name;
`Réponses:
Je viens de faire cela en fonction d'un code similaire que j'avais déjà, il semble fonctionner:
Usage::
Voir une démonstration de travail sur http://jsfiddle.net/alnitak/hEsys/
MODIFIER certains ont remarqué que ce code génèrerait une erreur s'il passait une chaîne où les index les plus à gauche ne correspondaient pas à une entrée correctement imbriquée dans l'objet. Il s'agit d'une préoccupation valable, mais à mon humble avis, il est préférable de traiter avec un
try / catch
bloc lors de l'appel, plutôt que de voir cette fonction retourner silencieusementundefined
pour un index non valide.la source
_.get(object, nestedPropertyString);
'part3[0].name.iDontExist'
. L'ajout d'une vérification pour voir sio
un objet figure dans leif in
correctif résout le problème. (La façon dont vous vous y prenez dépend de vous). Voir le violon mis à jour: jsfiddle.net/hEsys/418Voici la solution que j'utilise:
Exemple d'utilisation:
Limites:
[]
) pour les indices de tableau, bien que la spécification d'indices de tableau entre le jeton de séparation (par exemple,.
) fonctionne correctement, comme indiqué ci-dessus.la source
_.reduce()
partir de la bibliothèque de soulignement ou de lodash)self
n'est probablement pas défini ici. Tu veux direthis
?Ceci est maintenant supporté par lodash using
_.get(obj, property)
. Voir https://lodash.com/docs#getExemple de la documentation:
la source
_.set(...)
_.get
affichera le même comportement que lorsqu'aucune clé n'est trouvée dans l'objet fourni. par exemple_.get(null, "foo") -> undefined
,_.get(null, "foo", "bar") -> "bar"
. Cependant, ce comportement n'est pas défini dans les documents, donc sujet à changement.ES6 : Une seule ligne dans Vanila JS (elle retourne null si ne pas trouver au lieu de donner une erreur):
Ou exemple:
Avec opérateur de chaînage en option :
Pour une fonction prête à l'emploi qui reconnaît également les nombres faux, 0 et négatif et accepte les valeurs par défaut comme paramètre:
Exemple à utiliser:
Bonus :
Pour définir un chemin (demandé par @ rob-gordon), vous pouvez utiliser:
Exemple:
Tableau d'accès avec [] :
Exemple:
la source
let o = {a:{b:{c:1}}}; let str = 'a.b.c'; str.split('.').splice(0, str.split('.').length - 1).reduce((p,c)=>p&&p[c]||null, o)[str.split('.').slice(-1)] = "some new value";
0
,undefined
et lesnull
valeurs.{a:{b:{c:0}}}
renvoienull
au lieu de0
. Peut-être que la recherche explicite de null ou d'undefined permettra de résoudre ces problèmes.(p,c)=>p === undefined || p === null ? undefined : p[c]
Reflect.has(o, k) ? ...
(ES6 Reflect.has ) a bien fonctionnésetPath
définira la valeur à la première occurrence du dernier sélecteur. Par exemple,let o = {}; setPath(o, 'a.a', 0)
résulte en{a: 0}
plutôt qu'en{a: {a: 0}}
. voir cet article pour une solution.Vous devez analyser la chaîne vous-même:
Cela nécessitait que vous définissiez également les index de tableau avec la notation par points:
Cela facilite l'analyse.
DEMO
la source
[]
syntaxe en syntaxe de propriété est assez triviale.while (l > 0 && (obj = obj[current]) && i < l)
alors ce code fonctionne également pour les chaînes sans points.Fonctionne également pour les tableaux / tableaux à l'intérieur de l'objet. Défensif contre les valeurs invalides.
la source
en utilisant eval:
envelopper pour retourner indéfini en cas d'erreur
http://jsfiddle.net/shanimal/b3xTw/
Veuillez faire preuve de bon sens et de prudence lorsque vous utilisez la puissance de l'évaluation. C'est un peu comme un sabre laser, si vous l'allumez, il y a 90% de chances que vous coupiez un membre. Ce n'est pas pour tout le monde.
la source
Vous pouvez réussir à obtenir la valeur d'un membre d'objet profond avec la notation par points sans bibliothèque JavaScript externe avec la simple astuce suivante:
Dans votre cas pour obtenir une valeur de
part1.name
de lesomeObject
faire:Voici une démo de violon simple: https://jsfiddle.net/harishanchu/oq5esowf/
la source
Cela ne verra probablement jamais le jour ... mais le voici quand même.
[]
syntaxe des crochets par.
.
caractèreundefined
)la source
C'est une doublure avec du lodash.
Ou encore mieux ...
Ou version ES6 avec réduction ...
Plunkr
la source
Je pense que vous demandez ceci:
Vous pourriez demander ceci:
Qui fonctionneront tous les deux
Ou peut-être que vous demandez cela
Enfin, vous pourriez demander cela
la source
Split
méthode, mais plutôtsplit
.Ici, j'offre plus de moyens, qui semblent plus rapides à bien des égards:
Option 1: Split string activé. ou [ou] ou 'ou ", inversez-le, ignorez les éléments vides.
Option 2 (la plus rapide de toutes, sauf
eval
): Balayage de caractères de bas niveau (pas de regex / split / etc, juste un balayage rapide de caractères). Remarque: Celui-ci ne prend pas en charge les guillemets pour les index.Option 3: ( nouveau : option 2 étendue pour prendre en charge les devis - un peu plus lent, mais toujours rapide)
JSPerf: http://jsperf.com/ways-to-dereference-a-delimited-property-string/3
"eval (...)" est toujours roi (en termes de performances). Si vous avez des chemins de propriété directement sous votre contrôle, l'utilisation de 'eval' ne devrait pas poser de problème (surtout si la vitesse est souhaitée). Si vous tirez des chemins de propriété "sur le fil" ( sur la ligne !? Lol: P), alors oui, utilisez autre chose pour être en sécurité. Seul un idiot dirait de ne jamais utiliser "eval", car il y a de bonnes raisons de l'utiliser. En outre, "Il est utilisé dans l'analyseur JSON de Doug Crockford ." Si l'entrée est sûre, aucun problème. Utilisez le bon outil pour le bon travail, c'est tout.
la source
Au cas où quelqu'un visiterait cette question en 2017 ou plus tard et chercherait un moyen facile à retenir , voici un article de blog élaboré sur l' accès aux objets imbriqués en JavaScript sans être embrouillé par
Impossible de lire la propriété 'foo' d'une erreur non définie
Accéder aux objets imbriqués à l'aide de Array Reduce
Prenons cet exemple de structure
Pour pouvoir accéder aux tableaux imbriqués, vous pouvez écrire votre propre utilitaire de réduction de tableau.
Il existe également un excellent type de gestion de type de bibliothèque minimale qui fait tout cela pour vous.
Avec typy, votre code ressemblera à ceci
Avertissement: je suis l'auteur de ce package.
la source
AngularJS
L'approche de Speigg est très soignée et propre, bien que j'ai trouvé cette réponse en recherchant la solution d'accès aux propriétés de portée AngularJS $ par chemin de chaîne et avec une petite modification, elle fait le travail:
Placez simplement cette fonction dans votre contrôleur racine et utilisez-la dans n'importe quelle portée enfant comme ceci:
la source
$scope.$eval
pour une autre façon de le faire avec AngularJS.Je n'ai pas encore trouvé de package pour effectuer toutes les opérations avec un chemin de chaîne, j'ai donc fini par écrire mon propre petit package rapide qui prend en charge insert (), get () (avec retour par défaut), set () et remove ( ) opérations.
Vous pouvez utiliser la notation par points, les crochets, les indices de nombre, les propriétés de nombre de chaînes et les clés avec des caractères non-mot. Utilisation simple ci-dessous:
https://www.npmjs.com/package/jsocrud
https://github.com/vertical-knowledge/jsocrud
la source
Marche avec
la source
Fonction simple, permettant soit une chaîne soit un chemin de tableau.
OU
la source
Il existe
npm
maintenant un module pour ce faire: https://github.com/erictrinh/safe-accessExemple d'utilisation:
la source
Bien que réduire soit bon, je suis surpris que personne n'ait utilisé pour chacun:
Tester
la source
a.b.c
déclenchera une exception s'il n'y a pas de propriétéb
dans votre objet. Si vous avez besoin de quelque chose rejetant silencieusement le mauvais chemin de clavier (ce que je ne recommande pas), vous pouvez toujours remplacer le forEach par celui-cikeys.forEach((key)=> obj = (obj||{})[key]);
Je viens de poser la même question récemment et j'ai utilisé avec succès https://npmjs.org/package/tea-properties qui a également
set
imbriqué des objets / tableaux:avoir:
ensemble:
la source
Inspiré par la réponse de @ webjay: https://stackoverflow.com/a/46008856/4110122
J'ai fait cette fonction que vous pouvez utiliser pour obtenir / définir / annuler la valeur de n'importe quel objet
Pour l'utiliser:
la source
Je développe une boutique en ligne avec React. J'ai essayé de changer les valeurs dans l'objet d'état copié pour mettre à jour l'état d'origine avec lui lors de la soumission. Les exemples ci-dessus n'ont pas fonctionné pour moi, car la plupart d'entre eux modifient la structure de l'objet copié. J'ai trouvé un exemple de travail de la fonction pour accéder et modifier les valeurs des propriétés des objets imbriqués profonds: https://lowrey.me/create-an-object-by-path-in-javascript-2/ La voici:
la source
D'après la réponse d'Alnitak .
J'ai enveloppé le polyfill dans un chèque et réduit la fonction à une seule réduction enchaînée.
la source
Si vous devez accéder à différentes clés imbriquées sans le savoir au moment du codage (il sera trivial de les résoudre), vous pouvez utiliser l'accesseur de notation de tableau:
Ils sont équivalents à l'accesseur de notation par points et peuvent varier lors de l'exécution, par exemple:
est équivalent à
ou
J'espère que cela répondra à votre question ...
ÉDITER
Je n'utiliserai pas de chaîne pour conserver une sorte de requête xpath pour accéder à une valeur d'objet. Comme vous devez appeler une fonction pour analyser la requête et récupérer la valeur, je suivrais un autre chemin (pas:
ou, si vous n'êtes pas à l'aise avec la méthode d' application
Les fonctions sont plus courtes, plus claires, l'interprète les vérifie pour vous pour les erreurs de syntaxe et ainsi de suite.
Soit dit en passant, j'estime qu'une simple mission faite au bon moment sera suffisante ...
la source
Les solutions ici sont juste pour accéder aux clés profondément imbriquées. J'en avais besoin pour accéder, ajouter, modifier et supprimer les clés. Voici ce que j'ai trouvé:
path_to_key
: chemin dans un tableau. Vous pouvez le remplacer par votrestring_path.split(".")
.type_of_function
: 0 pour l'accès (ne transmettez aucune valeur àvalue
), 0 pour l'ajout et la modification. 1 pour supprimer.la source
S'appuyant sur la réponse d'Alnitak:
}
Cela vous permet également de définir une valeur!
J'ai aussi créé un paquet npm et github avec ça
la source
Au lieu d'une chaîne, un tableau peut être utilisé pour adresser des objets et des tableaux imbriqués, par exemple:
["my_field", "another_field", 0, "last_field", 10]
Voici un exemple qui changerait un champ basé sur cette représentation de tableau. J'utilise quelque chose comme ça dans react.js pour les champs d'entrée contrôlés qui changent l'état des structures imbriquées.
la source
Sur la base d'une réponse précédente, j'ai créé une fonction qui peut également gérer les crochets. Mais pas de points à l'intérieur en raison de la scission.
la source
la source
Travailler avec
Underscore
'sproperty
oupropertyOf
:Bonne chance...
la source