2010-12-13 65 views
8

J'ai un objet Javascript comme nichéJavascript: valeurs imbriquées l'accès à des données JSON en utilisant les noms de variables dynamiques

var data = { 'name': { 'heading': 'Name', 'required': 1, 'type': 'String' }, 
      'profile': { 
        'age': { 'heading': 'Age', 'required': 0, 'type': 'Number' }, 
        'phone': { 'heading': 'Phone', 'required': 0, 'type': 'String'}, 
        'city': { 'heading': 'City', 'required': 0, 'type': 'String'}, 
        }, 
      'status': { 'heading': 'Status', 'required': 1, 'type': 'String' } 
      }; 

Ici, je peux accéder aux champs data.profile.age.type ou data.name.type . Pas de problèmes Et si j'ai des noms de variables dynamiques, je peux accéder comme ci-dessous. Encore une fois, pas de problèmes.

f = 'profile'; data[f].age.type 

Mais, ici, j'ai les noms de variables comme 'nom', 'profile.age', 'profile.city' etc et, évidemment, je ne peux pas y accéder en tant que f = 'profile.age'; data [f] .type qui ne fonctionnera pas.

Quelqu'un peut-il me guider sur la façon d'y accéder (obtenir/régler) de la manière la plus directe et la plus simple?

Note: J'ai essayé ceci et cela fonctionne pour obtenir.

data.get = function(p) { o = this; return eval('o.'+p); }; 
f = 'profile.age'; data.get(f).name; 

bien que l'ensemble ne semble pas être assez simple. S'il vous plaît laissez-moi savoir, s'il y a de meilleures solutions pour obtenir et définir ainsi.

+2

Vous aviez raison de poser cette question sur le SO. Chaque fois que vous vous trouvez en utilisant eval dans Javascript, vous faites presque certainement la mauvaise chose. –

+0

Merci de m'avoir informé sur eval. Peut être eval est le mal! :-) – rsmoorthy

+0

Vous l'avez dit. Jetez un oeil à la dernière suggestion proposée ici: http://javascript.crockford.com/code.html –

Répondre

7

Ne pas utiliser eval sauf si absolument nécessaire. :) Au moins dans ce cas, il y a de meilleures façons de le faire - vous pouvez diviser le nom imbriqué dans des parties individuelles et itérer sur eux:

data.get = function(p) { 
    var obj = this; 

    p = p.split('.'); 
    for (var i = 0, len = p.length; i < len - 1; i++) 
    obj = obj[p[i]]; 

    return obj[p[len - 1]]; 
}; 

data.set = function(p, value) { 
    var obj = this; 

    p = p.split('.'); 
    for (var i = 0, len = p.length; i < len - 1; i++) 
    obj = obj[p[i]]; 

    obj[p[len - 1]] = value; 
}; 
+0

Merci. Réponse très rapide et utile. – rsmoorthy

8

Vous pouvez juste imbriquer les supports:

var a = 'name', b = 'heading'; 
data[a][b]; // = `Name` 
+1

cela ne répond pas à la question du tout ... – vsync

+1

@vsync: Bien sûr que oui. Je dis plutôt que 'var a = 'name.heading'; data [a] ', vous pouvez utiliser des ensembles successifs de parenthèses pour accéder à des niveaux plus profonds de l'objet. Donc, si vous savez que vous recherchez quelque chose dans l'objet 'profile',' var a = 'profile', b = 'age'; données [a] [b] 'fonctionne. Évidemment, si vous avez besoin de gérer une chaîne arbitraire, les autres réponses montrent comment faire cela. Ceci est une alternative si quelqu'un n'a pas besoin de la complexité de l'analyse syntaxique '' a.b.c.d "' chaînes. – josh3736

2

Peut-être une fonction qui prend dans le chemin à la propriété qui vous intéresse et il se décompose en jetons représentant propriétés. Quelque chose comme ça (ce qui est très difficile, bien sûr):

data.get = function(path) { 
    var tokens = path.split('.'), val = this[tokens[0]]; 
    if (tokens.length < 2) return val; 
    for(var i = 1; i < tokens.length; i++) { 
    val = val[tokens[i]]; 
    } 
    return val; 
} 

exemple:

var f = 'one.two'; 
    var data = { one: {two:'hello'}}; 
    data.get = /* same as above */; 

    var val = data.get(f); 
0

Il utilise la fonction jquery.each() pour traverser vers le bas un arbre json utilisant une variable chaîne pouvant contenir ou non un ou plusieurs "." Vous pouvez alternativement passer dans un tableau et omettre le .split();

pathString = quelque chose comme "person.name"

jsonObj = {quelque chose comme "personne": { "name": "valerie"}}.

function getGrandchild(jsonObj, pathString){ 
    var pathArray = pathString.split("."); 
    var grandchild = jsonObj; 
    $.each(pathArray, function(i, item){ 
     grandchild = grandchild[item]; 
    }); 
    return grandchild; 
}; 

retours "valerie"