如何在js中将对象数组转换为嵌套对象,反之亦然
How to convert array of object to nested object and vise versa in js
层次结构对象存储在层次结构中的对象数组
属性。对象的嵌套是基于此层次结构完成的
[
{
"hierarchy" : ["obj1"],
"prop1":"value"
},
{
"hierarchy" : ["obj1","obj2"],
"prop2":"value",
"prop3":"value"
},
{
"hierarchy" : ["obj1","obj3"],
"prop4":"value",
"prop5":"value"
},
{
"hierarchy" : ["obj1","obj3", "obj4"],
"prop6":"value",
"prop7":"value",
"arr" :["val1", "val2"]
}
]
预期的嵌套对象,此处删除了层次结构键
{
"obj1":{
"prop1":"value",
"obj2" : {
"prop2":"value",
"prop3":"value"
},
"obj3":{
"prop4":"value",
"prop5":"value",
"obj4" : {
"prop6":"value",
"prop7":"value",
"arr" :["val1", "val2"]
}
}
}
}
我试过但在第 8 行无法获取层次结构的代码
var input = "nested array as above";
var output = {};
var globalTemp = output;
for(var i = 0 ; i<input.length ; i++){
var tempObj = input[i];
for(var key in tempObj){
if(key == "hierarchy"){
globalTemp = globlalTemp[tempObj[key]] = {};
}
}
}
console.log(globalTemp);
您可以使用 forEach
和 reduce
方法并在内部创建当前对象的浅表副本并删除 hierarchy
属性.
const data = [{"hierarchy":["obj1"],"prop1":"value"},{"hierarchy":["obj1","obj2"],"prop2":"value","prop3":"value"},{"hierarchy":["obj1","obj3"],"prop4":"value","prop5":"value"},{"hierarchy":["obj1","obj3","obj4"],"prop6":"value","prop7":"value","arr":["val1","val2"]}]
const result = {}
data.forEach(function(o) {
o.hierarchy.reduce(function(r, e) {
const clone = Object.assign({}, o);
delete clone.hierarchy
return r[e] = (r[e] || clone)
}, result)
})
console.log(result)
使用较新版本的 javascript,您可以将 restparameters 用于所需的值 key/value 对,并通过保存最后一个 属性 来迭代给定的层次结构来构建嵌套结构=67=] 用于分配其余属性。
回收部分getFlat
使用数组作为堆栈,没有递归调用,以防止深度优先搜索试图首先获得最深度节点。
开始时,堆栈是一个数组,其中包含实际对象的数组和另一个包含空数组的对象 hierarchy
属性,因为实际上不知道对象的键.
然后 while
循环检查堆栈是否有一些项目,如果有,它获取堆栈的第一项并使用 destructuring assignment 获取对象 o
取回所有 key/value 对和另一个对象 temp
与单个 属性 hierarchy
和对象路径数组 o
.
push
标志设置为 false
,因为只有找到的属性才应该稍后推送到结果集。
现在检查对象的所有属性,如果
- 该值是真实的(以防止
null
值),
- 类型是一个对象(
null
是一个对象)并且
- 属性 不是数组
然后找到一个新对象进行检查。该对象被推送到具有实际路径的堆栈中。
如果没有,则找到一个值。这个 key/value 对被添加到 temp
对象并且标志被设置为 true
,以便稍后推送到结果集。
继续对象的键。
稍后检查 push
并将具有 hierarchy
属性 和自定义属性的 temp
对象推送到结果集。
function getFlat(object) {
var stack = [[object, { hierarchy: [] }]],
result = [],
temp, o, push;
while (stack.length) {
[o, temp] = stack.shift();
push = false;
Object.keys(o).forEach(k => {
if (o[k] && typeof o[k] === 'object' && !Array.isArray(o[k])) {
stack.push([o[k], { hierarchy: temp.hierarchy.concat(k) }]);
} else {
temp[k] = o[k];
push = true;
}
});
push && result.push(temp);
}
return result;
}
var data = [{ hierarchy: ["obj1"], prop1: "value" }, { hierarchy: ["obj1", "obj2"], prop2: "value", prop3: "value" }, { hierarchy: ["obj1", "obj3"], prop4: "value", prop5: "value" }, { hierarchy: ["obj1", "obj3", "obj4"], prop6: "value", prop7: "value", arr: ["val1", "val2"] }],
object = data.reduce((r, { hierarchy, ...rest }) => {
var last = hierarchy.pop();
hierarchy.reduce((o, k) => o[k] = o[k] || {}, r)[last] = rest;
return r;
}, {}),
reclaimedData = getFlat(object);
console.log(object);
console.log(reclaimedData);
.as-console-wrapper { max-height: 100% !important; top: 0; }
层次结构对象存储在层次结构中的对象数组
属性。对象的嵌套是基于此层次结构完成的
[
{
"hierarchy" : ["obj1"],
"prop1":"value"
},
{
"hierarchy" : ["obj1","obj2"],
"prop2":"value",
"prop3":"value"
},
{
"hierarchy" : ["obj1","obj3"],
"prop4":"value",
"prop5":"value"
},
{
"hierarchy" : ["obj1","obj3", "obj4"],
"prop6":"value",
"prop7":"value",
"arr" :["val1", "val2"]
}
]
预期的嵌套对象,此处删除了层次结构键
{
"obj1":{
"prop1":"value",
"obj2" : {
"prop2":"value",
"prop3":"value"
},
"obj3":{
"prop4":"value",
"prop5":"value",
"obj4" : {
"prop6":"value",
"prop7":"value",
"arr" :["val1", "val2"]
}
}
}
}
我试过但在第 8 行无法获取层次结构的代码
var input = "nested array as above";
var output = {};
var globalTemp = output;
for(var i = 0 ; i<input.length ; i++){
var tempObj = input[i];
for(var key in tempObj){
if(key == "hierarchy"){
globalTemp = globlalTemp[tempObj[key]] = {};
}
}
}
console.log(globalTemp);
您可以使用 forEach
和 reduce
方法并在内部创建当前对象的浅表副本并删除 hierarchy
属性.
const data = [{"hierarchy":["obj1"],"prop1":"value"},{"hierarchy":["obj1","obj2"],"prop2":"value","prop3":"value"},{"hierarchy":["obj1","obj3"],"prop4":"value","prop5":"value"},{"hierarchy":["obj1","obj3","obj4"],"prop6":"value","prop7":"value","arr":["val1","val2"]}]
const result = {}
data.forEach(function(o) {
o.hierarchy.reduce(function(r, e) {
const clone = Object.assign({}, o);
delete clone.hierarchy
return r[e] = (r[e] || clone)
}, result)
})
console.log(result)
使用较新版本的 javascript,您可以将 restparameters 用于所需的值 key/value 对,并通过保存最后一个 属性 来迭代给定的层次结构来构建嵌套结构=67=] 用于分配其余属性。
回收部分getFlat
使用数组作为堆栈,没有递归调用,以防止深度优先搜索试图首先获得最深度节点。
开始时,堆栈是一个数组,其中包含实际对象的数组和另一个包含空数组的对象 hierarchy
属性,因为实际上不知道对象的键.
然后 while
循环检查堆栈是否有一些项目,如果有,它获取堆栈的第一项并使用 destructuring assignment 获取对象 o
取回所有 key/value 对和另一个对象 temp
与单个 属性 hierarchy
和对象路径数组 o
.
push
标志设置为 false
,因为只有找到的属性才应该稍后推送到结果集。
现在检查对象的所有属性,如果
- 该值是真实的(以防止
null
值), - 类型是一个对象(
null
是一个对象)并且 - 属性 不是数组
然后找到一个新对象进行检查。该对象被推送到具有实际路径的堆栈中。
如果没有,则找到一个值。这个 key/value 对被添加到 temp
对象并且标志被设置为 true
,以便稍后推送到结果集。
继续对象的键。
稍后检查 push
并将具有 hierarchy
属性 和自定义属性的 temp
对象推送到结果集。
function getFlat(object) {
var stack = [[object, { hierarchy: [] }]],
result = [],
temp, o, push;
while (stack.length) {
[o, temp] = stack.shift();
push = false;
Object.keys(o).forEach(k => {
if (o[k] && typeof o[k] === 'object' && !Array.isArray(o[k])) {
stack.push([o[k], { hierarchy: temp.hierarchy.concat(k) }]);
} else {
temp[k] = o[k];
push = true;
}
});
push && result.push(temp);
}
return result;
}
var data = [{ hierarchy: ["obj1"], prop1: "value" }, { hierarchy: ["obj1", "obj2"], prop2: "value", prop3: "value" }, { hierarchy: ["obj1", "obj3"], prop4: "value", prop5: "value" }, { hierarchy: ["obj1", "obj3", "obj4"], prop6: "value", prop7: "value", arr: ["val1", "val2"] }],
object = data.reduce((r, { hierarchy, ...rest }) => {
var last = hierarchy.pop();
hierarchy.reduce((o, k) => o[k] = o[k] || {}, r)[last] = rest;
return r;
}, {}),
reclaimedData = getFlat(object);
console.log(object);
console.log(reclaimedData);
.as-console-wrapper { max-height: 100% !important; top: 0; }