我有一个这样的对象:
{
"root.apple.color": "red",
"root.apple.shape": "circle",
"root.peach[0].color": "green",
"root.peach[1].color": "yellow",
}
如何将其转换为这样的对象:
{
"root": {
"apple": {
"color": "red",
"shape": "circle"
},
"peach": [
{
"color": "green"
},
{
"color": "yellow"
}
]
}
}
基本上我需要一个函数,它将任何数组定义为顶级示例转换为具有真实参数的多级对象。
答案 0 :(得分:1)
使用Object.keys
,String.split
,Array.isArray
,Array.forEach
函数的扩展解决方案:
var obj = {
"root.apple.color": "red",
"root.apple.shape": "circle",
"root.peach[0].color": "green",
"root.peach[0].shape": "square",
"root.peach[1].color": "yellow",
"root.apple.info.items[0].type": "text",
"root.apple.info.items[0].active": true,
"root.apple.info.items[1].type": "image",
"root.apple.info.items[1].active": false,
"root.apple.exterior.toggle[0].id": "left",
"root.apple.exterior.toggle[0].content": "Ext",
"root.test": "testing"
},
result = {};
function transformObject(obj, result) {
var current,
checkProp = function (prop, objItem, is_array, idx, val) {
if (Array.isArray(current) && val) {
if (typeof idx === 'number' && current[idx]){
current[idx][prop] = val;
} else {
var o = {};
o[prop] = val;
current.push(o);
}
} else {
objItem[prop] = objItem[prop] || ((!is_array) ? {} : []);
if (val) objItem[prop] = val;
current = objItem[prop];
}
},
re = /\[(\d)\]$/;
Object.keys(obj).forEach(function (k) {
var props = k.split("."),
lastKey = props.length - 1,
val = obj[k], idx;
props.forEach(function (prop, k) {
var is_array = re.test(prop);
if (is_array) { idx = +prop.match(re)[1]; prop = prop.replace(re, ""); };
checkProp(prop, (!current) ? result : current, is_array, idx, (k === lastKey) ? val : null);
});
current = null;
});
return result;
}
console.log(JSON.stringify(transformObject(obj, result), 0, 4));
答案 1 :(得分:0)
此实现仅适用于对象嵌套。你可以自己添加阵列感知。
function nested(obj, strPropertyChain, value) {
var props = strPropertyChain.split('.');
var len = props.length;
var o = obj[props[0]] = (obj[props[0]] || {});
props.slice(1, len - 1)
.forEach(prop => o = (o[prop] = {}));
o[props[len - 1]] = value;
return obj;
}
var obj1 = {
"root.apple.color": "red",
"root.apple.shape": "circle",
"root.peach.color": "green",
"root.pear.color": "yellow",
}
var obj2 = {}
Object.keys(obj1).forEach(k => nested(obj2, k, obj1[k]));
console.log(obj2);

答案 2 :(得分:0)
你可以这样做;
Object.prototype.setNestedValue = function(...a) {
a.length > 2 ? typeof this[a[0]] === "object" && this[a[0]] !== null ? this[a[0]].setNestedValue(...a.slice(1))
: (this[a[0]] = isNaN(a[1]) ? {} : new Array(a[1]),
this[a[0]].setNestedValue(...a.slice(1)))
: this[a[0]] = a[1];
return this;
};
var data = {
"root.apple.color": "red",
"root.apple.shape": "circle",
"root.peach[0].color": "green",
"root.peach[1].color": "yellow",
},
ok = Object.keys(data),
o = ok.reduce((o,k) => o.setNestedValue(...k.replace("[",".").replace("]","").split(".").concat(data[k])),{});
console.log(JSON.stringify(o));

Object.prototype.setNestedValue()
接受一系列参数,其中最后一个是值,而前一个是,如果字符串类型是嵌套对象属性,或者是整数,数组索引。我不得不将你的对象键变成像"root.peach[0].color": "green"
- >这样的数组。 ["root, "peach", "0", "color", "green"]
。然后Object.prototype.setNestedValue()
会告诉" 0"实际上是一个数组索引。