javascript – 从键/值对创建复杂对象

前端之家收集整理的这篇文章主要介绍了javascript – 从键/值对创建复杂对象前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

我有一个具有键/值对的文件.该文件通过Docker加载到process.env中.但是出于开发目的,我手动加载它,所以最后它们是相同的;

配置:

  1. process.env['ccc.logger.winston.level']='info';
  2. process.env['ccc.logger.winston.transports.type.file']='File';
  3. process.env['ccc.logger.winston.transports.filename']='logs/testOne.log';
  4. process.env['ccc.logger.winston.transports.rotate']='false';
  5. process.env['ccc.logger.winston.transports.type.file']='File';
  6. process.env['ccc.logger.winston.transports.filename']='logs/testTwo.log';
  7. process.env['ccc.logger.winston.transports.rotate']='true';

我的期望是拥有这个目标:

  1. {
  2. "ccc": {
  3. "logger": {
  4. "winston": {
  5. "level": "info","transports": [
  6. {
  7. "type": "File","filename": "logs/testONE.log","rotate": true
  8. },{
  9. "type": "File","filename": "logs/testTWO.log","rotate": false
  10. }
  11. ]
  12. }
  13. }
  14. }
  15. }

我已经提出了可行的解决方案,但如果我有一个对象数组,我遇到了问题,就像上面的例子一样:

循环所有键/值的函数调用函数来创建对象:

  1. let ENV_FROM_DOCKER = process.env;
  2. for (let property in ENV_FROM_DOCKER) {
  3. let checkForShallowProperties = property.split(".")[1];
  4. if (typeof checkForShallowProperties === 'undefined') {
  5. continue;
  6. }
  7. let resultObject = this.expand(property,ENV_FROM_DOCKER[property]););
  8. emptyConfig = merge(emptyConfig,resultObject);
  9. let stop;
  10. }

对象创建功能

  1. expand(str,value) {
  2. let items = str.split(".") // split on dot notation
  3. let output = {} // prepare an empty object,to fill later
  4. let ref = output // keep a reference of the new object
  5. // loop through all nodes,except the last one
  6. for (let i = 0; i < items.length - 1; i++) {
  7. ref[items[i]] = {}; // create a new element inside the reference
  8. ref = ref[items[i]]; // shift the reference to the newly created object
  9. }
  10. ref[items[items.length - 1]] = value; // apply the final value
  11. return output // return the full object
  12. }

这个设置工作正常,但如果我有一个对象数组的对象(如上面的例子),它不能正常工作.这是现在的输出

  1. {
  2. "ccc": {
  3. "logger": {
  4. "winston": {
  5. "level": "info","transports": {
  6. "type": {
  7. "file": "File"
  8. },"filename": "logs/testTwo.log","rotate": "true"
  9. }
  10. }
  11. }
  12. }
  13. }

我试图让这段代码现在工作几个小时,但只是在圈子里旋转. ccc对象就是一个例子.键/值列表中还有其他对象也可能包含数组.

最佳答案
为每个传输分配索引

在创建环境变量时,您可以将每个transports.whatnot分配给数组中的索引传输[0] .whatnot和transports [1] .whatnot.为了完成这项工作,我们必须像这样解析它:

  1. const ENV = {
  2. 'ccc.logger.winston.level': 'info','ccc.logger.winston.transports[0].type': 'File','ccc.logger.winston.transports[0].filename': 'logs/testOne.log','ccc.logger.winston.transports[0].rotate': 'false','ccc.logger.winston.transports[1].type': 'File','ccc.logger.winston.transports[1].filename': 'logs/testTwo.log','ccc.logger.winston.transports[1].rotate': 'true'
  3. }
  4. for (let property in ENV) {
  5. let checkForShallowProperties = property.split('.')[1];
  6. if (typeof checkForShallowProperties === 'undefined') {
  7. continue;
  8. }
  9. let resultObject = expand(property,ENV[property])
  10. console.log(resultObject)
  11. }
  12. function expand(string,value) {
  13. const items = string.split('.').map(name => {
  14. const match = name.match(/\[\d+?\]/)
  15. return {
  16. name: match ? name.slice(0,match.index) : name,usesBrackets: !!match,key: match && match[0].slice(1,-1)
  17. }
  18. })
  19. const output = {}
  20. let ref = output
  21. let parent
  22. for (const item of items) {
  23. ref[item.name] = {}
  24. parent = ref
  25. ref = ref[item.name]
  26. if (item.usesBrackets) {
  27. ref[item.key] = {}
  28. ref = ref[item.key]
  29. }
  30. }
  31. parent[items[items.length - 1].name] = value
  32. return output
  33. }

这里的输出是PRE-MERGE

正如您所看到的,它的工作方式是将对象视为自己的数组,并将内容放在索引或甚至其他访问器中.

但是,将所有这些转移到.json文件或某个内容管理系统最有可能符合您的最佳利益,因为这是一种非常不稳定的处理方式.如果您的需求发生了变化,您可能需要重写它,使用JSON您只需加载JSON即可.

猜你在找的Docker相关文章