如何获取对象的给定子节点的JSON路径?
E.g:
var data = {
key1: {
children: {
key2:'value',
key3:'value',
key4: { ... }
},
key5: 'value'
}
给出了一个引用key4的变量。现在我正在寻找绝对的道路:
data.key1.children.key4
有没有办法在JS中完成这项工作?
提前谢谢。
答案 0 :(得分:9)
所以你有一个值为“key3”的变量,你想知道如何根据这个字符串的值动态访问这个属性吗?
var str = "key3";
data["key1"]["children"][str];
修改强>
哇,我不敢相信我第一次尝试这个。可能存在一些错误,但它适用于您的测试用例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']
答案 1 :(得分:5)
这就是我这样做的方式。
/**
* 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
希望能帮助别人。
答案 2 :(得分:0)
我的解决方案:
(可以使用此deep_value
函数来检索结果。)
var key4Ref = { abc: 123 }
var data = {
key1: {
children: {
key2:'value',
key3:'value',
key4: key4Ref
},
key5: 'value'
}
}
// find the path to a 'ref' within an object 'data'.
const pathTo = (ref, data, path = []) => {
const found = data && Object.entries(data).find(([k,v]) => {
if (v === ref) return path.push(k)
if (typeof v === 'object') {
const tmp = pathTo(ref, v, [...path, k])
if (tmp) return path = tmp
}
})
if (found) return path
}
console.log(pathTo(key4Ref, data).join('.'))
答案 3 :(得分:-1)
$response = file_get_contents('https://www.instagram.com/instagram/?__a=1');
$result = json_decode($response, true);
var_dump($result);
var data = {
// Your data is here
a: {
b: {
c: {
d: "Assalamu alal muslimin"
}
}
},
// Your function is here
take: function(path) {
var temp = this; // take a copy of object
if(!path) return temp; // if path is undefined or empty return the copy
path = path.split("/");
for(var p in path) {
if(!path[p]) continue; // means "a/" = "a"
temp = temp[path[p]]; // new data is subdata of data
if(!temp) return temp;
}
return temp;
}
};
简而言之,功能是:
<input placeholder="Please enter the path"/>
<button onclick="document.querySelector('div').innerText = JSON.stringify(data.take(document.querySelector('input').value))">
Try it
</button>
<br><br>
Data: {a:{b:{c:{d:"Assalamu alal muslimin"}}}}
<br><br>
Code: data.take(path)
<br><br>
Result:
<div></div>
最短的函数,但如果输入错误的路径,则可能会出错:
function getDataByPath(data, path) {
if(!path) return data; // if path is undefined or empty return data
path = path.split("/");
for(var p in path) {
if(!path[p]) continue; // "a/" = "a"
. data = data[path[p]]; // new data is subdata of data
if(!data) return data; // "a/b/d" = undefined
}
return data;
}