递归遍历javascript对象并用键替换值
由于JSON不能执行函数,我需要通过JSON对象中的键标志来计算JSON字符串。我想在JSON数据为对象形式时对其进行变异 我在网上找不到一个函数/方法可以根据已知的密钥模式提供密钥的完整路径 鉴于这些数据:递归遍历javascript对象并用键替换值,javascript,json,node.js,recursion,Javascript,Json,Node.js,Recursion,由于JSON不能执行函数,我需要通过JSON对象中的键标志来计算JSON字符串。我想在JSON数据为对象形式时对其进行变异 我在网上找不到一个函数/方法可以根据已知的密钥模式提供密钥的完整路径 鉴于这些数据: { "js:bindto": "#chart-1", // note the key here 'js:' "point": { "r": 5 }, "data": { "x": "x", "xFormat
{
"js:bindto": "#chart-1", // note the key here 'js:'
"point": {
"r": 5
},
"data": {
"x": "x",
"xFormat": "%Y",
"columns": [
...
],
"colors": {
"company": "#ed1b34",
"trendline": "#ffffff"
}
},
"legend": {
"show": false
},
"axis": {
"x": {
"padding": {
"left": 0
},
"type": "timeseries",
"tick": {
"format": "%Y",
"outer": false
}
},
"y": {
"tick": {
"outer": false,
"js:format": "d3.format(\"$\")" // note the key here 'js:'
}
}
},
"grid": {
"lines": {
"front": false
},
"y": {
"lines": [...]
}
}
}
这些标志是以js:
开头的键
如果我查找js:format
,我希望它的路径类似于:/js:bindto
和/axis/y/tick/js:format
。接受建议
在这方面:
mutateGraphData<T>(data:T):T {
// data here is a parsed JSON string. ( an object as shown above )
let jsonKeys = this.findKeysInJSON(JSON.stringify(data), "js:");
// jsonKeys = ["js:bindto","js:format"]
jsonKeys.map((key:string) => {
// find the key in data, then modify the value. (stuck here)
// i need the full path to the key so i can change the data property that has the key in question
});
});
return data;
}
findKeysInJSON<T>(jsonString:string, key:string):Array<T> {
let keys = [];
if (Boolean(~(jsonString.indexOf(`"${key}`)))) {
let regEx = new RegExp(key + "(\\w|\\-)+", "g");
keys = jsonString.match(regEx);
}
return keys;
}
mutateGraphData(数据:T):T{
//这里的数据是经过解析的JSON字符串。(如上所示的对象)
让jsonKeys=this.findKeysInJSON(JSON.stringify(数据),“js:”);
//jsonKeys=[“js:bindto”,“js:format”]
jsonKeys.map((key:string)=>{
//在数据中找到键,然后修改值。(卡在此处)
//我需要密钥的完整路径,以便可以更改包含该密钥的数据属性
});
});
返回数据;
}
findKeysInJSON(jsonString:string,key:string):数组{
让键=[];
if(布尔(~(jsonString.indexOf(`“${key}')){
设regEx=newregexp(key+“(\\w | \ \-)+”,“g”);
keys=jsonString.match(regEx);
}
返回键;
}
我已经了解了一些npm软件包:
- 没有外卡环顾四周
- 看起来不错,但搜索失败:“*.js:format”
- -需要钥匙的完整路径。我事先不知道
- 违抗TJS(无npm模块)
R.lensPath
,允许您挖掘对象,并根据需要进行修改。它不遵循您想要的模式,但我们可以使用lensify
功能快速修补它
它使用R.set
函数将节点设置为传入值,并创建一个管道,在传入对象上运行所有操作
你可以用ramda和镜头做一些非常酷的事情。请在livecoding.tv上查看evilsoft,获得非常好的概述
(代码>代码>警察局)的警察局(代码>警察局)的警察局(代码)的警察局(代码)的警察局(代码)的警察局(代码)的警察局(代码)的警察局(代码)的警察局(代码)的警察局(代码)的警察局(代码)的警察局(公司)的警察局(公司)的警察局(公司)的警察局(公司)的警察局(公司)的(公司)的(公司)的(公司)的(公司)的(公司:公司:公司:公司:公司:公司:公司:公司:公司:公司:公司:公司:公司:公司:公司:公司:公司:公司:公司:公司:公司:公司:公司:公司:公司:公司:公司:公司:公司:公司:公司:公司:公司:公司:公司:公司:工:公司:公司:公司:公司:公司:公司:公司:公司:公司:公司:公司:公司:公司:公司:公司:公司:公司:公司:公司:公司:公司:公司:公司:公司:[]}}}
const lensify=path=>R.lensPath(path.split('/'))
//创建按拆分的属性访问器/
const bindToLens=lensify('js:bindto')
const formatLens=lensify('axis/y/tick/js:format')
const modifyObj=R.pipe(
R.set(bindToLens,'dis be bind'),
R.set(formatLens,“我来过这里”)
)
console.log(modifyObj(obj))
环顾四周后,我修改了@adam rackis的答案
function search(obj, target, path = "") {
for (var k in obj) {
if (obj.hasOwnProperty(k))
if (k === target)
return path + "." + k;
else if (typeof obj[k] === "object") {
var result = search( obj[k], target, path + "." + k );
if (result){
return result;
}
}
}
return false;
}
search(data,"js:format").slice(1); // returns: axis.y.tick.js:format
search(data,"js:bindto").slice(1); // returns: js:bindto
现在我可以使用dotty
或object resolve path
或纯olesplit('.')
来解析对象的路径。这应该是一个单行程序。我们已经在数据处理中大量使用了它,只要你仔细考虑一下它,它就会非常强大。下面是如何使用它
//const objectScan=require('object-scan');
const find=(数据)=>objectScan(['**.js:'],{joined:true})(数据);
常量数据={'js:bindto':'#chart-1',点:{r:5},数据:{x:'x',x格式:'%Y',列:[],颜色:{company:'#ed1b34',趋势线:'#ffffff'},图例:{show:false},轴:{x:{padding:{left:0},类型:'timeseries',tick:{format:'%Y',outer:false},Y:{tick:'outer:false:'js format:''d3},Y:'{lines:{front:false},y:{lines:[]}};
console.log(查找(数据));
//=>['axis.y.tick.js:format','js:bindto']
。作为控制台包装{最大高度:100%!重要;顶部:0}
什么是语言的mutateGraphData(data:T):T
?@NinaScholz:TypeScript@georg watch这需要几个小时才能理解,但值得付出很多努力。不过还是在第6行,我需要知道完整的路径才能修改该属性。