Javascript / JSON получить путь к данному подузлу? - PullRequest
10 голосов
/ 09 января 2012

Как бы вы получили JSON-путь к данному дочернему узлу объекта?

например:.

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

Дана переменная со ссылкой на key4. Сейчас я ищу абсолютный путь:

data.key1.children.key4

Есть ли способ сделать это в JS?

Заранее спасибо.

Ответы [ 2 ]

10 голосов
/ 09 января 2012

Итак, у вас есть переменная со значением «key3», и вы хотите знать, как динамически обращаться к этому свойству, основываясь на значении этой строки?

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

EDIT

Ничего себе, я не могу поверить, что я получил это с первой попытки.В нем могут быть некоторые ошибки, но это работает для вашего тестового примера

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']
5 голосов
/ 14 января 2016

Я так и сделал.

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

Для тестирования

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

Надеюсь, что это кому-нибудь поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...