2012-01-09 11 views
8

Jak uzyskać ścieżkę JSON do danego węzła podrzędnego obiektu?JavaScript/JSON uzyskać ścieżkę do danego podwęzła?

Np .:

var data = { 
    key1: { 
     children: { 
      key2:'value', 
      key3:'value', 
      key4: { ... } 
     }, 
    key5: 'value' 
} 

Zmienna z odniesieniem do KEY4 podano. Teraz szukam absolutnej ścieżki:

data.key1.children.key4 

Czy jest jakiś sposób, aby to zrobić w JS?

Z góry dziękuję.

+0

Jeśli zmienna wyszukiwania wskazuje na obiekt tekstowy (jak w przykładzie), nie będzie można wiarygodnie wyszukać tej ścieżki jako (na przykład) 'data.key1.children.key3 === data.key4' byłaby również "prawdziwa" i prawdopodobnie nie to, co próbujesz osiągnąć. – Yoshi

+0

Dzięki Yoshi, zaktualizowałem próbkę kodu. Teraz odnośnik wskazuje na inny obiekt. – user1138959

Odpowiedz

8

Masz więc zmienną o wartości "key3" i chcesz wiedzieć, jak uzyskać dostęp do tej właściwości w sposób dynamiczny, na podstawie wartości tego ciągu?

var str = "key3"; 
data["key1"]["children"][str]; 

EDIT

Wow, nie mogę uwierzyć, że dostaliśmy to za pierwszym razem. Nie może być w nim kilka błędów, ale to działa w Twoim przypadku testowego

LIVE DEMO

var x = data.key1.children.key4; 

var path = "data"; 
function search(path, obj, target) { 
    for (var k in obj) { 
     if (obj.hasOwnProperty(k)) 
      if (obj[k] === target) 
       return path + "['" + k + "']" 
      else if (typeof obj[k] === "object") { 
       var result = search(path + "['" + k + "']", obj[k], target); 
       if (result) 
        return result; 
      } 
    } 
    return false; 
} 

var path = search(path, data, x); 
console.log(path); //data['key1']['children']['key4'] 
+0

Cześć Adam, dziękuję za odpowiedź. Szukam pełnej ścieżki. "key1" i "children" są nieznane. Mam odniesienie do data.key1.children.key3 przechowywane w zmiennej i trzeba wiedzieć, jak się tam dostać. – user1138959

+0

@ user1138959 - Nie jestem pewien, czy to możliwe. To znaczy, możesz zrobić rekursywne przeszukiwanie przez każdego członka obiektu, ale nadal nie będzie możliwości sprawdzenia, którego członka wskazywał twoja zmienna, gdybyś miał wartości, które były takie same –

+0

Zaktualizowałem przykład mojego kodu. Szukam obiektu, a nie wartości ciągu. Jak mogę rekurencyjnie przeszukać każdego członka i uzyskać ścieżkę do pasującego dziecka? – user1138959

4

To jest sposób w jaki zostało to zrobione.

/** 
* Converts a string path to a value that is existing in a json object. 
* 
* @param {Object} jsonData Json data to use for searching the value. 
* @param {Object} path the path to use to find the value. 
* @returns {valueOfThePath|undefined} 
*/ 
function jsonPathToValue(jsonData, path) { 
    if (!(jsonData instanceof Object) || typeof (path) === "undefined") { 
     throw "Not valid argument:jsonData:" + jsonData + ", path:" + path; 
    } 
    path = path.replace(/\[(\w+)\]/g, '.$1'); // convert indexes to properties 
    path = path.replace(/^\./, ''); // strip a leading dot 
    var pathArray = path.split('.'); 
    for (var i = 0, n = pathArray.length; i < n; ++i) { 
     var key = pathArray[i]; 
     if (key in jsonData) { 
      if (jsonData[key] !== null) { 
       jsonData = jsonData[key]; 
      } else { 
       return null; 
      } 
     } else { 
      return key; 
     } 
    } 
    return jsonData; 
} 

Do testowania

var obj = {d1:{d2:"a",d3:{d4:"b",d5:{d6:"c"}}}}; 
jsonPathToValue(obj, "d1.d2"); // a 
jsonPathToValue(obj, "d1.d3"); // {d4: "b", d5: Object} 
jsonPathToValue(obj, "d1.d3.d4"); // b 
jsonPathToValue(obj, "d1.d3.d5"); // {d6: "c"} 
jsonPathToValue(obj, "d1.d3.d5.d6"); // c 

nadzieję, że komuś pomóc.

Powiązane problemy