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

Eri*_*icz 1 javascript json

假设我有以下 JSON,它可以轻松地来回转换为 JavaScript 对象:

{
    "foo": {
        "bar": "Common substitute word",
        "baz": "Another common substitute word",
        "questionWords": {
            "wat": "Inadequate question word",
            "wut": "Even more inadequate question word"
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我在另一个 JSON 文件中收到有关此 JSON 的修改,如下所示:

{
    "foo.questionWords.wut": "A question word to avoid"
}
Run Code Online (Sandbox Code Playgroud)

所以要修改的路径以字符串形式给出。我必须通过新数据修改第一个 JSON。

但也可能不存在新的数据路径:

{
    "foo.callingWords.dude": "Commonly used synonym for pal"
}
Run Code Online (Sandbox Code Playgroud)

并且新的数据路径可能具有不可确定的深度

{
    "who.knows.how.deep.we.will.go": "Look, a penny!"
}
Run Code Online (Sandbox Code Playgroud)

在没有 JS 库的情况下,仅通过普通的 Vanilia JS 处理此问题的最佳方法是什么?

(您可以使用最新的 JavaScript 功能。)

感谢您的帮助!

Kos*_*ery 6

切勿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))
Run Code Online (Sandbox Code Playgroud)

  • 这行是杀手`steps.forEach(e => (k[e] = k[e] || {}) && (k = k[e]));` 谢谢! (2认同)