Javascript:嵌套对象引用的点符号字符串

Javascript:嵌套对象引用的点符号字符串,javascript,object,Javascript,Object,我们正在尝试根据点符号字符串设置嵌套对象值 输入示例: { "bowtime": [ "30", " 1", " 3", " 20" ], "bowstate.levi.leviFlo.totalFloQuot": ".95", "bowstate.crem.cremQuot": "79" } 期望输出: { "bowstate": { "levi": { "l

我们正在尝试根据点符号字符串设置嵌套对象值

输入示例:

{
    "bowtime": [
       "30",
       " 1",
       " 3",
       " 20"
    ],
    "bowstate.levi.leviFlo.totalFloQuot": ".95",
    "bowstate.crem.cremQuot": "79" 
}
期望输出:

{
    "bowstate": {
       "levi": {
           "leviFlo": {
               "totalFloQuot": 0.95
           }
       },
       "crem": {
           "cremQuot": 79
       }
    },
    "bowtime": [
       "30",
       " 1",
       " 3",
       " 20"
    ],
}
到目前为止,代码运行良好,但似乎过于复杂,只允许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]]
  }
}
const dayspace={};
var keyArr=Object.keys(输入);
用于(输入keyArr){
if(keyArr[key].indexOf('.')>-1){
var setArr=keyArr[key].split('.');
dayspace[setArr[0]]=dayspace[setArr[0]]| |{
对于(var s=0;ss+1)天空间[setArr[0]][setArr[s]]={}
else dayspace[setArr[0]][setArr[s]=req.body[keyArr[key]]
}
如果(s==2){
如果(setArr.length>s+1)dayspace[setArr[0]][setArr[1]][setArr[s]]={}
else dayspace[setArr[0]][setArr[1]][setArr[s]]=req.body[keyArr[key]]
}
如果(s==3){
如果(setArr.length>s+1)天空间[setArr[0]][setArr[1]][setArr[2]][setArr[s]]={}
else dayspace[setArr[0]][setArr[1]][setArr[2]][setArr[s]]=req.body[keyArr[key]]
}
如果(s==4)天空间[setArr[0]][setArr[1]][setArr[2]][setArr[3]][setArr[s]]=req.body[keyArr[key]]
}
}
否则{
dayspace[keyArr[key]=req.body[keyArr[key]]
}
}

我将键拆分为
并使用
reduce
创建除最后一个嵌套值以外的所有值(如果需要),然后将该值分配给reduce回调中创建或找到的最后一个对象:

const输入={
“bowtime”:[
"30",
" 1",
" 3",
" 20"
],
“bowstate.levi.leviFlo.totalFloQuot”:“.95”,
“bowstate.crem.cremQuot”:“79”
};
const output=Object.entries(input).reduce((outerObj[key,val])=>{
如果(!key.includes('.')){
outerObj[key]=val;
返回ROBJ;
}
const keys=key.split('.');
const lastKey=keys.pop();
const lastObj=键。reduce((a,键)=>{
//如果此键不存在,请在此键处创建对象:
如果(!一个[键]){
a[键]={};
}
返回一个[键];
},outerObj);
//我们现在有了对最后创建的对象(或已经存在的对象)的引用
//因此,只需指定值:
lastObj[lastKey]=val;
返回ROBJ;
}, {});

console.log(output);
我将键拆分为
并使用
reduce
创建除最后一个嵌套值以外的所有值(如果需要),然后将该值分配给reduce回调中创建或找到的最后一个对象:

const输入={
“bowtime”:[
"30",
" 1",
" 3",
" 20"
],
“bowstate.levi.leviFlo.totalFloQuot”:“.95”,
“bowstate.crem.cremQuot”:“79”
};
const output=Object.entries(input).reduce((outerObj[key,val])=>{
如果(!key.includes('.')){
outerObj[key]=val;
返回ROBJ;
}
const keys=key.split('.');
const lastKey=keys.pop();
const lastObj=键。reduce((a,键)=>{
//如果此键不存在,请在此键处创建对象:
如果(!一个[键]){
a[键]={};
}
返回一个[键];
},outerObj);
//我们现在有了对最后创建的对象(或已经存在的对象)的引用
//因此,只需指定值:
lastObj[lastKey]=val;
返回ROBJ;
}, {});

console.log(output);
我在我的项目中也做过类似的事情。我用一个名为Flat的流行软件包实现了它。Link:

这个软件包可以使嵌套结构扁平化,也可以使嵌套结构扁平化。还有其他有用的方法。所以它会更灵活


我认为您应该使用它,这将减少项目中的bug。

我在项目中也做过类似的事情。我通过一个名为Flat的流行软件包实现了这一点。链接:

这个软件包可以使嵌套结构扁平化,也可以使嵌套结构扁平化。还有其他有用的方法。所以它会更灵活


我认为您应该使用它,这将减少项目中的错误。

您可以使用
Object.entires
在对象中获得一个键值对数组,然后使用
.split(“.”)来
.reduce()
对象键
要将单个对象属性放入数组中,然后使用该数组构建新对象,请执行以下操作:

const obj={
“bowtime”:[
"30",
" 1",
" 3",
" 20"
],
“bowstate.levi.leviFlo.totalFloQuot”:“.95”,
“bowstate.crem.cremQuot”:“79”
};
常量res=Object.entries(obj).reduce((acc[k,v])=>{
常量键=k.split('.');
设cur=acc;
keys.length>1&&keys.forEach(ka=>{
cur[ka]=cur[ka]|{};
cur=cur[ka];
});
cur[keys.pop()]=v;
返回acc;
}, {});

console.log(res);
您可以使用
Object.entires
在对象中获取键值对数组,然后使用
.split(“.”)将单个对象属性获取到数组中,然后使用该数组构建新对象:

const obj={
“bowtime”:[
"30",
" 1",
" 3",
" 20"
],
“bowstate.levi.leviFlo.totalFloQuot”:“.95”,
“bowstate.crem.cremQuot”:“79”
};
常量res=Object.entries(obj).reduce((acc[k,v])=>{
常量键=k.split('.');
设cur=acc;
keys.length>1&&keys.forEach(ka=>{
cur[ka]=cur[ka]|{};
cur=cur[ka];
});
cur[keys.pop()]=v;
返回acc;
}, {});

console.log(res);
您可以使用一种较短的方法,使用一个函数作为值的拆分路径,并为其生成新对象

函数设置值(对象、路径、值){
var last=path.pop();
reduce((o,k)=>o[k]=o[k]| |{},object)[last]=value;
}
var object={bowtime:[“30”、“1”、“3”、“20”]、“bowstate.levi.leviFlo.totalFloQuot”:.95”、“bowstate.crem.cremQuot”:“79”};
Object.entries(Object.forEach)([ke]
var unflatten = require('flat').unflatten

unflatten({
    'three.levels.deep': 42,
    'three.levels': {
        nested: true
    }
})

// {
//     three: {
//         levels: {
//             deep: 42,
//             nested: true
//         }
//     }
// }