2010-12-13 8 views
8

Mam zagnieżdżony obiekt JavaScript jakJavascript: Dostęp zagnieżdżone wartości w danych JSON z wykorzystaniem dynamicznych nazw zmiennych

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

Tutaj mogę uzyskać dostęp do pól jako data.profile.age.type lub data.name.type . Brak problemów A jeśli mam nazwy zmiennych dynamicznych, mogę uzyskać dostęp, jak poniżej. Znowu nie ma problemów.

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

Ale tutaj mam nazwy zmiennych takich jak 'nazwa', 'profile.age', 'profile.city' itp i oczywiście nie mogę mieć do nich dostęp jako 'f' profile.age =; dane [f] .typ, które nie będą działać.

Czy każdy może podpowiedzieć mi, jak uzyskać do nich dostęp (uzyskać/ustawić) w najprostszy i najprostszy sposób?

Uwaga: próbowałem tego i działa w trybie get.

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

Chociaż zestaw nie wydaje się być wystarczająco prosty. Daj mi znać, jeśli istnieją lepsze rozwiązania również w zakresie pobierania i ustawiania.

+2

Miałeś rację zadać to pytanie na SO. Za każdym razem, gdy używasz eval w JavaScript, prawie na pewno robisz coś niewłaściwego. –

+0

Dzięki za poinformowanie mnie o eval. Może być eval jest złe! :-) – rsmoorthy

+0

Powiedziałeś to. Zapoznaj się z ostatnią propozycją oferowaną tutaj: http://javascript.crockford.com/code.html –

Odpowiedz

7

Nie używaj eval chyba że jest to absolutnie konieczne. :) Przynajmniej w tym przypadku, są lepsze sposoby, aby to zrobić - można podzielić zagnieżdżony nazwę na poszczególne części i iteracyjne nad nimi:

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

Dzięki. Bardzo szybka reakcja i pomocna. – rsmoorthy

8

można po prostu zagnieżdżać nawiasy:

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

to nie odpowiada na pytanie w ogóle ... – vsync

+1

@vsync: Oczywiście, że tak. Mówię to raczej niż "var a =" name.heading "; data [a] ', możesz użyć kolejnych zestawów nawiasów, aby uzyskać dostęp do głębszych poziomów obiektu. Więc jeśli wiesz, że szukasz czegoś w obiekcie 'profile',' var a = 'profile', b = 'age'; Dane [a] [b] 'działają. Oczywiście, jeśli potrzebujesz obsługi dowolnego ciągu znaków, inne odpowiedzi pokazują, jak to zrobić. Jest to alternatywa, jeśli ktoś nie potrzebuje złożoności parsowania dowolnych ciągów "a.b.d". – josh3736

2

Może to funkcja, która bierze na drodze do nieruchomości, które Cię interesują i rozbija go na żetony reprezentujące właściwości. Coś jak to (jest to bardzo szorstki, oczywiście):

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

przykład:

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

    var val = data.get(f); 
0

ta wykorzystuje funkcję jQuery.each(), aby przechodzić w dół drzewo json używające zmiennej łańcuchowej, która może zawierać lub nie jedną lub więcej ".". Można alternatywnie przekazać tablicę i pominąć .split();

pathString = coś "person.name"

jsonObj = coś podobnego { "osoby": { "name": "Valerie"}}.

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

powraca "Valerie"

Powiązane problemy