Javascript/JSON获取指定子节点的路径
Javascript/JSON get path to given subnode?
如何获得对象的给定子节点的JSON路径?
例如:
var data = {
key1: {
children: {
key2:'value',
key3:'value',
key4: { ... }
},
key5: 'value'
}
给出了一个引用关键字4的变量。现在我正在寻找绝对路径:
data.key1.children.key4
有什么方法可以在JS中完成这项工作吗?
提前谢谢。
所以您有一个值为"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']
我就是这样做的。
/**
* 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|null}
*/
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
希望这能帮助到别人。
我的解决方案:
- 基于给定参考的深度优先搜索
- 使用递归
- 处理数组
(使用此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('.'))
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;
}
以及最短的函数,但如果您输入错误的路径,它可能会出错:
function getDataByPath(data, path) {
for(var i in path.split("/")) data = data[path[i]];
return data;
}
let x;
try{
x = JSON.parse(prompt("Input your JSON"))
}
catch(e) {
alert("not a valid json input")
}
var res = {};
var constructResultCurry = function(src){ return constructResult(res,src); }
function constructResult(target, src) {
if(!src) return;
target[src.key] = src.val;
}
function buildPath(key, obj, overAllKey) {
overAllKey += (overAllKey ? "." : "") + key;
if(typeof obj[key] != "object") return { key : overAllKey, val : obj[key] };
Object.keys(obj[key]).forEach(function(keyInner) {
constructResultCurry(buildPath(keyInner, obj[key], overAllKey));
});
}
Object.keys(x).forEach(function(k){
constructResultCurry(buildPath(k, x, ""));
});
console.log("**************ALL FIELDS****************")
console.log(res);
console.log("******************************************")
let conf = confirm("do you need a specific field from JSON");
if ( conf )
{
let field = prompt("Input field name")
let results = Object.fromEntries(
Object.entries(res).filter(([key]) => (key.toLowerCase()).includes((field.toLowerCase()))))
prompt("Copy to clipboard: Ctrl+C, Enter", JSON.stringify(results));
console.log(results)
}
else {
prompt("Copy to clipboard: Ctrl+C, Enter", JSON.stringify(res));
}
上面的解决方案返回整个json,其中每个字段都有一个完整的路径。还有请求的特定字段的路径。
我也在努力解决这个问题,JSON路径也包括数组,这就是我最终想到的方法:
function findValuePath(obj, value) {
// Initialize the array of results and the array of paths
let result = [];
let path = [];
// Recursive functions look up values
function searchValue(obj, value) {
for (let key in obj) {
// If the current attribute value is equal to the target value, the path is logged
if (obj[key] === value) {
path.push((Array.isArray(obj) ? `[${key}]` : `.${key}`));
result = path.slice();
path.pop();
}
// If the current property is an object or array, search recursively
else if (typeof obj[key] === 'object') {
path.push((Array.isArray(obj) ? `[${key}]` : `.${key}`));
searchValue(obj[key], value);
path.pop();
}
}
}
// Call the recursive function
searchValue(obj, value);
//If the target value is found, the path string is returned, otherwise an empty string is returned
return result.length > 0 ? result.join('') : '';
}
这是我做的测试示例:
let obj = {
a:1,
b:"hello",
c:{
a:"target000",
b:"tar",
c:"target_w",
d:[
"target0",
"target1",
"target2",
{
a:2,
b:"target"
}
]
}
}
let res = findValuePath(obj,"target")
console.log(res) // ".c.d[3].b"
console.log(`obj${res}`) // "obj.c.d[3].b"
console.log(eval(`obj${res}`)) // "target"
相关文章:
- 选择<李>使用普通JavaScript的子节点,而不是孙节点
- js循环遍历单击的元素子节点
- 如何将数据添加到json的子节点
- 删除HTML节点而不删除其子节点
- 如何在javascript DOM api中获取具有给定条件的子节点
- 仅使用某些子节点访问xml中父节点的子节点
- 检测单击子节点并发送槽事件处理程序
- 从 d3.js 中的树中选择节点的子节点
- 访问所选剑道树视图节点的子节点
- 为什么正文标记后的脚本标记在子节点中计数
- 难以获取使用属性选择的节点的子节点
- 使用Javascript设置带有子节点的父节点的类's文本等于.
- 如何确定父节点是否有子节点
- 在没有 jquery 的情况下更改子节点(父节点具有 ID)中的链接文本
- Javascript - 子节点计数
- 在子节点上重复
- 如何在D3.js基于力的标签布局图中获取公共子节点
- 如何访问React中的子节点
- 在树布局中选择子节点的所有路径和父节点
- 如何在对象内部搜索子节点,并在找到时返回相关路径