Javascript:点表示法字符串到嵌套对象引用

BTE*_*EVC 2 javascript object

我们尝试根据点表示法字符串设置嵌套对象值。

输入示例:

{
    "bowtime": [
       "30",
       " 1",
       " 3",
       " 20"
    ],
    "bowstate.levi.leviFlo.totalFloQuot": ".95",
    "bowstate.crem.cremQuot": "79" 
}
Run Code Online (Sandbox Code Playgroud)

期望的输出:

{
    "bowstate": {
       "levi": {
           "leviFlo": {
               "totalFloQuot": 0.95
           }
       },
       "crem": {
           "cremQuot": 79
       }
    },
    "bowtime": [
       "30",
       " 1",
       " 3",
       " 20"
    ],
}
Run Code Online (Sandbox Code Playgroud)

到目前为止,代码运行良好,但看起来过于复杂,并且只允许 4 层嵌套。我们如何简化此代码,并使其适用于嵌套超过 4 层的引用:

const dayspace = {};
var keyArr = Object.keys(input);

for (key in keyArr) {
  if ( keyArr[key].indexOf('.') > -1 ) {
    var setArr = keyArr[key].split('.');
    dayspace[setArr[0]] = dayspace[setArr[0]] || {}
    for (var s = 0; s < setArr.length; s++) {
      if (s == 1) {
        if (setArr.length > s + 1) dayspace[setArr[0]][setArr[s]] = {}
        else dayspace[setArr[0]][setArr[s]] = req.body[keyArr[key]]
      }
      if (s == 2) {
        if (setArr.length > s + 1) dayspace[setArr[0]][setArr[1]][setArr[s]] = {}
        else dayspace[setArr[0]][setArr[1]][setArr[s]] = req.body[keyArr[key]]
      }
      if (s == 3) {
        if (setArr.length > s + 1) dayspace[setArr[0]][setArr[1]][setArr[2]][setArr[s]] = {}
        else dayspace[setArr[0]][setArr[1]][setArr[2]][setArr[s]] = req.body[keyArr[key]]
      }
      if (s == 4) dayspace[setArr[0]][setArr[1]][setArr[2]][setArr[3]][setArr[s]] = req.body[keyArr[key]]
    }
  }
  else {
    dayspace[keyArr[key]] = req.body[keyArr[key]]
  }
}
Run Code Online (Sandbox Code Playgroud)

Cer*_*nce 6

如果需要的话,我会将键拆分.并用于reduce创建除最后一个嵌套值之外的所有值,然后将该值分配给在reduce回调中创建或找到的最后一个对象:

const input = {
    "bowtime": [
       "30",
       " 1",
       " 3",
       " 20"
    ],
    "bowstate.levi.leviFlo.totalFloQuot": ".95",
    "bowstate.crem.cremQuot": "79" 
};

const output = Object.entries(input).reduce((outerObj, [key, val]) => {
  if (!key.includes('.')) {
    outerObj[key] = val;
    return outerObj;
  }
  const keys = key.split('.');
  const lastKey = keys.pop();
  const lastObj = keys.reduce((a, key) => {
    // Create an object at this key if it doesn't exist yet:
    if (!a[key]) {
      a[key] = {};
    }
    return a[key];
  }, outerObj);
  // We now have a reference to the last object created (or the one that already existed
  // so, just assign the value:
  lastObj[lastKey] = val;
  return outerObj;
}, {});
console.log(output);
Run Code Online (Sandbox Code Playgroud)