[英]JavaScript: Change data in JSON by string data path
假设我有以下JSON,可以轻松地将其来回转换为JavaScript对象:
{
"foo": {
"bar": "Common substitute word",
"baz": "Another common substitute word",
"questionWords": {
"wat": "Inadequate question word",
"wut": "Even more inadequate question word"
}
}
}
我在另一个JSON文件中收到有关此JSON的修改 ,如下所示:
{
"foo.questionWords.wut": "A question word to avoid"
}
因此,修改路径以字符串形式给出 。 而且我必须通过新数据修改第一个JSON。
但是新的数据路径也可能不存在:
{
"foo.callingWords.dude": "Commonly used synonym for pal"
}
新的数据路径的深度可能不确定 :
{
"who.knows.how.deep.we.will.go": "Look, a penny!"
}
没有普通的Vanilia JS就没有JS库的最佳解决方法是什么?
(您可以使用最新的JavaScript功能。)
谢谢您的帮助!
切勿将eval
用于此类任务。 分割您的“路径”并逐步进行:
var data = { "foo": { "bar": "Common substitute word", "baz": "Another common substitute word", "questionWords": { "wat": "Inadequate question word", "wut": "Even more inadequate question word" } } }, mods = { "foo.questionWords.wut": "A question word to avoid", "foo.callingWords.dude": "Commonly used synonym for pal", "who.knows.how.deep.we.will.go": "Look, a penny!" }; function apply(data, mods) { for (var path in mods) { var k = data; var steps = path.split('.'); var last = steps.pop(); steps.forEach(e => (k[e] = k[e] || {}) && (k = k[e])); k[last] = mods[path]; } return data } console.log(apply(data, mods))
本质上与每个人的答案相同,只是避免使用eval(),如果这可能是个问题。
var obj={ "foo": { "bar": "Common substitute word", "baz": "Another common substitute word", "questionWords": { "wat": "Inadequate question word", "wut": "Even more inadequate question word" } } } var obj2={ "foo.questionWords.wut": "A question word to avoid" } for(var i in obj2){ var res = i.split("."); var fieldName = res.splice(res.length-1,1); var objField = res.reduce((r, u) => r && r[u] ? r[u] : '' , obj); objField[fieldName]=obj2[i]; } console.log(obj);
我的解决方案使用递归函数。
const modifyObject = (object, jsonPath, value) => { const keys = jsonPath.split("."); const key = keys.splice(0, 1); if (keys.length > 0) { modifyObject(object[key], keys.join('.'), value) } else { object[key] = value; } } const obj = { foo: { bar: 11, baz: 12, bac: { leng: 1, str: 'hello world' } } }; modifyObject(obj, 'foo.bac.leng', 'modified'); console.log(JSON.stringify(obj));
在命令式风格中,我只是变异源代码:
updateAll = function(source, target) {
Object.keys(target)
.forEach((k) => update(source, k, target[k]));
}
update = function(source, targetKey, targetValue) {
var keys = targetKey.split('.');
// Iterate as long as there are keys to shift out and as long as source is
// defined for that key.
while((key = keys.shift()) && source[key]) {
// If we're at a leaf, assign new value. Otherwise, iterate further into
// the object.
if (keys.length === 0 && typeof source[key] !== 'object') {
source[key] = targetValue;
} else {
source = source[key];
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.