【问题标题】:Write data to a nested dictionary given a "key path" of unknown length给定长度未知的“关键路径”,将数据写入嵌套字典
【发布时间】:2020-11-01 18:20:59
【问题描述】:

我的应用程序有一个文件,其中包含(在字典中)有关应用程序的一般信息,例如设置。 主要词典是:

"info": {}

要写入文件,我的write 函数需要两个参数。 data 和一个 key。例如,如果我有这个:

"info": {
    "settings": {
        "appearance": "dark"
    }
}

要写信给appearance,我会首先阅读整个settings,然后修改appearance,最后将其全部写回文件。像这样:

let new_settings = File.read("settings");
new_settings.appearance = "light";
File.write(new_settings, "settings");
//////////// data ///////// key ///

这是一个write 函数,所以我不必自己修改数据。我想到了能够使用“关键路径”的想法。有了这个新的“关键路径”,我所要做的就是:

File.write("light", "settings > appearance");

settings > appearance 说的是under settings, under appearance, write "light"。不幸的是,除了像这样使用字符串和 eval 之外,我想不出任何更好的方法来实现这一点:

let path = "d[\"info\"]";

///"keys" is an array of the keys in the key path
///"settings > appearance" = ["settings","appearance"]

for (let i = 0; i < keys.length; i++) {
    path = path.concat("[\"", keys[i], "\"]");
    if (!eval(path)) {
        eval(path.concat(" = {}"));
    }
    if (i === keys.length - 1) {
        //"data" is the data passed into the write function
        eval(path.concat(" = data"));
    }
}

我总是会遇到写字典的问题。它很容易阅读,因为您可以遍历键并继续分配给同一个变量,直到达到所需的变量:

d = d[key]

但是你需要写信的那一刻:

d[key1][key2]//.....

当您不知道键的数量时,您需要编辑我发现很难做到的主字典。 这样做有什么好处?

【问题讨论】:

  • 将您的设置文件视为 JSON,这样您就可以轻松地转换、操作、存储或通过网络发送
  • 我正在将其转换为 JSON 对象,但除非我遗漏了某些内容,否则这对我没有帮助,因为您访问 JSON 对象中的数据的方式与访问字典的方式相同,所以我仍然会结束同样的问题

标签: javascript dictionary object


【解决方案1】:

如果你有一个 JSON 对象和一个键路径:

function updateSettings(settings, keyPath, value) {
  const keys = keyPath.split('.');
  const targetKey = keys.pop();
  let current = settings;
  for (let i = 0; i < keys.length; ++i) {
    current = current[keys[i]];
    if (!current) {
      throw new Error('Specified key not found. ' + keys[i]);
    }
  }
  current[targetKey] = value;
  // return settings; // optional, because it changes settings object directly
}

const settings = {
  root: 0,
  settings: {
    appearance: 'light'
  },
  some: {
    very: {
      very: {
        nested: {
          value: 1
        }
      }
    }
  }
};

updateSettings(settings, 'settings.appearance', 'dark');
updateSettings(settings, 'root', 1024);
updateSettings(settings, 'some.very.very.nested.value', 2048);

输出是:

{
  root: 1024,
  settings: {
    appearance: 'dark'
  },
  some: {
    very: {
      very: {
        nested: {
          value: 2048
        }
      }
    }
  }
};

一些库(例如lodash _.get)有这方面的实现方法。

【讨论】:

  • 哦,有趣。你看我想如果你有对象A(比如{"test":{"test1":"1}}),你让对象B等于A["test"]然后做了B["test1"] = "2"它不会改变A。现在我想起来,这没有任何意义,但那是我当时的想法。
猜你喜欢
  • 1970-01-01
  • 2015-09-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-12
  • 2018-10-27
相关资源
最近更新 更多