繁体   English   中英

JavaScript:按字符串数据路径更改JSON中的数据

[英]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)) 

vanillaJS中的选项之一,您可以使用eval (但请害怕,非常害怕!),如下所示:

var t = {
    "foo": {
        "bar": "Common substitute word",
        "baz": "Another common substitute word",
        "questionWords": {
            "wat": "Inadequate question word",
            "wut": "Even more inadequate question word"
        }
    }
};

eval("t.foo.bar = 13")

在此处输入图片说明

本质上与每个人的答案相同,只是避免使用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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM