我们试图基于点表示法字符串设置嵌套对象的值。
示例输入:
{
"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层嵌套。我们如何简化此代码,并使它适用于具有四层以上嵌套的引用:
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]]
}
}
答案 0 :(得分:2)
我将键除以.
并使用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);
答案 1 :(得分:1)
我在项目中做过类似的事情。我已经通过一个名为Flat的流行软件包实现了它。链接:https://github.com/hughsk/flat
var unflatten = require('flat').unflatten
unflatten({
'three.levels.deep': 42,
'three.levels': {
nested: true
}
})
// {
// three: {
// levels: {
// deep: 42,
// nested: true
// }
// }
// }
此软件包可以使您的嵌套结构变平,也使嵌套结构变平。还有其他有用的方法。因此它将更加灵活。
我认为您应该使用它,这样可以减少项目中的错误。
答案 2 :(得分:1)
您可以使用较短的方法,即使用函数来分割值的路径并为其生成新对象。
function setValue(object, path, value) {
var last = path.pop();
path.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(([key, value]) => {
if (!key.includes('.')) return;
setValue(object, key.split('.'), value);
delete object[key];
});
console.log(object);
.as-console-wrapper { max-height: 100% !important; top: 0; }
答案 3 :(得分:0)
您可以使用Object.entires
获取对象内的键-值对数组,然后使用.reduce()
将对象的单个键属性.split(".")
放入数组,然后可以用来构建新对象:
const obj = {
"bowtime": [
"30",
" 1",
" 3",
" 20"
],
"bowstate.levi.leviFlo.totalFloQuot": ".95",
"bowstate.crem.cremQuot": "79"
};
const res = Object.entries(obj).reduce((acc, [k, v]) => {
const keys = k.split('.');
let cur = acc;
keys.length > 1 && keys.forEach(ka => {
cur[ka] = cur[ka] || {};
cur = cur[ka];
});
cur[keys.pop()] = v;
return acc;
}, {});
console.log(res);