将数组(多个深度对象键)转换为一个对象

Transfrom array (multiple depth object keys) into one object

任务: 将键数组转换为一个对象,并为每个键分配一个空字符串,例如 ("").

问题: 键还表示结果对象中的不同深度级别(例如 defaultToolConf.graph.graphApiConf.url 表示对象中的 4 个深度级别)。 每个深度级别在关键字符串中由点 (.) 分隔。

输入(数组):

[
'ADMIN_URL_REGEXP', 
'BASE_PATH', 
'appName', 
'defaultToolConf',
'defaultToolConf.graph', 
'defaultToolConf.graph.graphApiConf', 
'defaultToolConf.graph.graphApiConf.markerCampaignsUrl',
'defaultToolConf.graph.graphApiConf.markerUrl', 
'defaultToolConf.graph.graphApiConf.ndviUrl', 
'defaultToolConf.graph.graphLineColors', 
'defaultToolConf.query', 
'defaultToolConf.query.canExportKml', 
'defaultToolConf.query.isExportEnabled', 
'defaultToolConf.query.isResizable', 
'defaultToolConf.test', 
'defaultToolConf.toolsPermissionsPath', 
'token', 
'token.format', 
'token.key', 
'token.paths'
]

输出(结果对象):

{
    "ADMIN_URL_REGEXP": "",
    "BASE_PATH": "",
    "appName": "",
    "defaultToolConf": {
        "graph": {
            "graphApiConf": {
                "markerCampaignsUrl": "",
                "markerUrl": "",
                "ndviUrl": ""
            },
            "graphLineColors": ""
        },
        "query": {
            "canExportKml": "",
            "isExportEnabled": "",
            "isResizable": ""
        },
        "test": "",
        "toolsPermissionsPath": ""
    },
    "tokenInterceptor": {
        "format": "",
        "key": "",
        "paths": ""
    }
}

到目前为止我做了什么:https://jsfiddle.net/rt279mfz/

我设法创建了一个包含多个深度对象的结果对象。

问题: 我必须将键值分配为空对象 {}。这意味着我将不得不遍历所有对象键(在多个深度)并将值重新分配为空字符串而不是空对象。不知道可不可以。

我在结果对象中有重复键。

您可以“遍历”对象,边走边创建子关卡。这是一个例子:

const array = [
    'ADMIN_URL_REGEXP', 
    'BASE_PATH', 
    'appName', 
    'defaultToolConf',
    'defaultToolConf.graph', 
    'defaultToolConf.graph.graphApiConf', 
    'defaultToolConf.graph.graphApiConf.markerCampaignsUrl',
    'defaultToolConf.graph.graphApiConf.markerUrl', 
    'defaultToolConf.graph.graphApiConf.ndviUrl', 
    'defaultToolConf.graph.graphLineColors', 
    'defaultToolConf.query', 
    'defaultToolConf.query.canExportKml', 
    'defaultToolConf.query.isExportEnabled', 
    'defaultToolConf.query.isResizable', 
    'defaultToolConf.test', 
    'defaultToolConf.toolsPermissionsPath', 
    'token', 
    'token.format', 
    'token.key', 
    'token.paths'];
    
const arrayToObject = (arr) => {
  return arr.reduce((acc, el) => {
    let currentNode = acc;
    const pathParts = el.split(".");
    for (let i = 0; i < pathParts.length - 1; i++) { // skip the final element (- 1)
      let pp = pathParts[i];
      if (!currentNode[pp])
        currentNode[pp] = {}; // create the nested object if needed
      currentNode = currentNode[pp]; // move to the next level of the object
    }
    // currentNode is now the parent object of the last property from the array that we need to add, from here we just assign it to ""
    currentNode[pathParts[pathParts.length - 1]] = "";
    return acc;
  }, {});
}

let newObject = arrayToObject(array);
console.log(newObject);

迭代:

// Reduce 
const result = array.reduce((acc, item) => {

  // Split string to array
  const split = item.split('.');

  let currentStep = acc;

  split.forEach((item, index) => {
    // Set current object property (if already exists do nothing, if not then create an empty object, if its last index assign empty string)
    currentStep = currentStep[item]
                = (currentStep[item] || (index === split.length - 1 ? '' : {}))

  });

  return acc;

}, {})

递归:

const result = array.reduce((acc, item) => {

  const createDeepNestedObj = (obj, array, index = 0, current = array[index]) => {

    obj[current] = obj[current] || (index < array.length - 1 ? {} : '');

    if (index < array.length) createDeepNestedObj(obj[current], array, ++index);
  }

  createDeepNestedObj(acc, item.split('.'));

  return acc;

}, {})