简体   繁体   English

如何简化修改 JSON 对象的 JavaScript 代码

[英]How to simplify JavaScript code modifying an JSON object

So the goal is to have included only those endpoints (and its methods eg get, post...) which are defined in the configuration file.因此,目标是仅包含配置文件中定义的那些端点(及其方法,例如 get、post...)。

Example structure object that holds all the endpoints.包含所有端点的示例结构对象。

et swaggerApis = {
  header: {
    propertyHeader: "valueHeader"
  },
  blocks: [
    {
      tags: ["Tenant & User"],
      paths: {
        "/tenants": {
          post: {
            property: "value"
          },
          get: {
            property: "value"
          }
        },
        "/tenants/{id}": {
          post: {
            property: "value"
          },
          get: {
            property: "value"
          },
          delete: {
            property: "value"
          }
        }
      }
    }
  ]
};

Example of the configuration file that holds only those endpoints and its methods we want to have included in the final object.仅包含我们希望包含在最终对象中的那些端点及其方法的配置文件示例。

const CONFIG = {
  api: {
    include: {
      "/tenants/{id}": ["get"]
    }
  }
};

So far here is my second version of the JavaScript code that works but introduces a high cyclometric complexity and is hard to read.到目前为止,这是我的 JavaScript 代码的第二个版本,它可以工作,但引入了高循环复杂度并且难以阅读。 I'm pretty new to JavaScript and looking a way not just to improve this code.我对 JavaScript 很陌生,正在寻找一种不仅可以改进此代码的方法。

function includeEnpointsByConfig(data) {
  for (let blockItem of data.blocks) {
    for (let path in blockItem.paths) { //console.log(blockItem.paths[path])
      let result = setMethodsOfEndpoint(path, blockItem.paths[path]);
      if (result === 'undefined') {
        delete blockItem.paths[path] // if the config does not contain, remove
      } else {
        blockItem.paths[path] = result;
      }
    }
  }
  return data;
}

function setMethodsOfEndpoint(path, value) {
  let newMethods = {};

  for (let confPath in CONFIG.api.include) {
    if (path === confPath) { // match endpoint in config and swaggerApis object
      if (CONFIG.api.include[confPath].length > 0) { // if array in config is not empty , filter
        for (let c of CONFIG.api.include[confPath]) { //console.log(c); // get
          for (let v in value) {// properties of object tenants/{id} => {get{}, post{}}
            if (v === c) {
              newMethods = { ...newMethods, [v]: value[v] };
            }
          }
        }
      } else {// if array in config is empty , return param "value" from setMethodsOfEndpoint so we will include all methods of endpoint
        return value;
      }
  } else {
    return 'undefined'
  }
}
if (Object.keys(newMethods).length !==0) { // if in the config is in the array (nothing that match with swaggerEndpoints e.g. typo get --> gte)
  return newMethods
}  else {
  return value;
}
}

console.log(includeEnpointsByConfig(swaggerApis));

Code can be found also here https://codesandbox.io/s/blazing-worker-1emzl?file=/src/index2.js代码也可以在这里找到https://codesandbox.io/s/blazing-worker-1emzl?file=/src/index2.js

I believe there is a way to do it much easier, cleaner and more effective.我相信有一种方法可以更轻松、更清洁、更有效。 Thank you谢谢

With some creative usage of Array.prototype.forEach() , Object.keys() and Object.entries() : Array.prototype.forEach()Object.keys()Object.entries()一些创造性用法:

swaggerApis.blocks.forEach(block => {
  Object.entries(block.paths).forEach(([path, methods]) => {
    if (!CONFIG.api.include[path]) {
      delete block.paths[path];
    } else {
      Object.keys(methods).forEach(method => {
        if (!CONFIG.api.include[path].includes(method)) {
          delete methods[method];
        }
      });
    }
  });
});

Complete snippet:完整片段:

 const swaggerApis = { header: { propertyHeader: "valueHeader" }, blocks: [ { tags: ["Tenant & User"], paths: { "/tenants": { post: { property: "value" }, get: { property: "value" } }, "/tenants/{id}": { post: { property: "value" }, get: { property: "value" }, delete: { property: "value" } } } } ] }; const CONFIG = { api: { include: { "/tenants/{id}": ["get"] } } }; swaggerApis.blocks.forEach(block => { Object.entries(block.paths).forEach(([path, methods]) => { if (!CONFIG.api.include[path]) { delete block.paths[path]; } else { Object.keys(methods).forEach(method => { if (!CONFIG.api.include[path].includes(method)) { delete methods[method]; } }); } }); }); console.log(swaggerApis);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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