2010-12-13 13 views
8

Ho un oggetto JavaScript annidato comeJavascript: i valori di accesso annidati nei dati JSON utilizzando i nomi delle variabili dinamiche

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' } 
      }; 

Qui, posso accedere ai campi come data.profile.age.type o data.name.type . Nessun problema E se ho nomi di variabili dinamiche, posso accedere come sotto. Di nuovo, nessun problema.

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

Ma, qui ho i nomi delle variabili come il 'nome', 'profile.age', etc 'profile.city' e ovviamente non posso accedere come f 'profile.age'; data [f] .type che non funzionerà.

Qualcuno può guidarmi su come accedervi (ottenere/impostare) nel modo più diretto e semplice?

Nota: ho provato questo e funziona per ottenere.

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

sebbene set non sembra essere abbastanza semplice. Per favore fatemi sapere, se ci sono soluzioni migliori per ottenere e impostare pure.

+2

hai fatto bene a porre questa domanda su SO. Ogni volta che ti ritrovi a usare eval in Javascript, stai quasi certamente facendo la cosa sbagliata. –

+0

Grazie per avermi fatto conoscere la valutazione. Può essere eval è il male! :-) – rsmoorthy

+0

Lo hai detto tu. Dai un'occhiata all'ultimo suggerimento offerto qui: http://javascript.crockford.com/code.html –

risposta

7

Non utilizzare eval se non assolutamente necessario. :) Almeno in questo caso, ci sono modi migliori per farlo - è possibile dividere il nome annidato in singole parti e scorrere su di loro:

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

Grazie. Risposta molto rapida e utile. – rsmoorthy

8

Si può solo nido le staffe:

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

questo non risponde affatto alla domanda ... – vsync

+1

@vsync: certo che lo fa. Sto dicendo che piuttosto che 'var a = 'name.heading'; dati [a] ', puoi usare serie successive di parentesi per accedere ai livelli più profondi dell'oggetto. Quindi, se sai che stai cercando qualcosa nell'oggetto 'profile',' var a = 'profile', b = 'age'; dati [a] [b] 'funziona. Ovviamente, se devi gestire una stringa arbitraria, le altre risposte mostrano come farlo. Questa è un'alternativa se qualcuno non ha bisogno della complessità dell'analisi di stringhe arbitrarie "a.b.c.d". – josh3736

2

Forse una funzione che prende nel percorso per la proprietà che ti interessa e si rompe in su in gettoni che rappresentano proprietà. Qualcosa di simile (questo è molto ruvida, ovviamente):

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; 
} 

esempio:

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

    var val = data.get(f); 
0

Questo utilizza la funzione jquery.each() per attraversare verso il basso un albero json che utilizza una variabile stringa che può contenere o meno uno o più "." In alternativa potresti passare in un array e omettere il .split();

pathString = qualcosa come "person.name"

jsonObj = qualcosa come { "persona": { "name": "Valerie"}}.

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

restituisce "Valerie"

Problemi correlati