我想将我的对象转换为嵌套对象,以便能够在响应中递归地渲染输入(如果输入在此输入之下具有子输入渲染)有时输入顺序错误,所以我必须像这样转换对象/ p>
const start = {
asdf: {
id: "asdf",
question: "How old are you?",
type: "text"
},
"asdf/zxcv": {
id: "asdf/zxcv",
expect: 18,
question: "Are you male?",
type: "text"
},
"asdf/zxcv/yuio": {
id: "asdf/zxcv/yuio",
expect: "yes",
question: "Do you like videogames?",
type: "text"
},
"asdf/dfgh": {
id: "asdf/dfgh",
expect: 21,
question: "Where do you live?",
type: "text"
},
"asdf/dfgh/fghj": {
id: "asdf/dfgh/fghj",
expect: "Boston",
question: "What's the weather?",
type: "text"
},
qwer: {
id: "qwer",
question: "What is your name?",
type: "text"
},
"qwer/asdf": {
id: "qwer/asdf",
expect: "David",
question: "What is your surname",
type: "text"
}
};
变成这样
const result = {
asdf: {
id: "asdf",
question: "How old are you?",
type: "text",
subs: [
{
id: "asdf/zxcv",
expect: 18,
question: "Are you male?",
type: "text",
subs: [
{
id: "asdf/zxcv/yuio",
expect: "yes",
question: "Do you like videogames?",
type: "text"
}
]
},
{
id: "asdf/dfgh",
expect: 21,
question: "Where do you live?",
type: "text",
subs: [
{
id: "asdf/dfgh/fghj",
expect: "Boston",
question: "What's the weather?",
type: "text"
}
]
}
]
},
qwer: {
id: "qwer",
question: "What is your name?",
type: "text",
subs: [
{
id: "qwer/asdf",
expect: "David",
question: "What is your surname",
type: "text"
}
]
}
};
我可以创建对象的第一级,但是我不知道如何在需要时向潜艇动态添加对象
这是我的尝试。它不起作用。
const createObjToRender = object => {
Object.values(object)
.filter(o => o)
.reduce((obj, el) => {
const idHistory = el.id.split("/");
if (idHistory.length > 1) {
let elToAddSubInput = obj;
for (let i = 0; i <= idHistory.length; i++) {
i === 0 && (elToAddSubInput = elToAddSubInput[idHistory[i]]);
i > 0 && (elToAddSubInput = elToAddSubInput.subs[idHistory[i]]);
}
elToAddSubInput.subs[idHistory.join("/")] = el;
}
if (idHistory.length === 1) {
const id = idHistory[0];
const { question, type } = el;
if (!obj[id]) {
obj[id] = {
id,
question,
type,
subs: {}
};
}
}
}, {});
};
答案 0 :(得分:2)
您可以使用嵌套的哈希表快速构建树:
const start = {
asdf: {
id: "asdf",
question: "How old are you?",
type: "text"
},
"asdf/zxcv": {
id: "asdf/zxcv",
expect: 18,
question: "Are you male?",
type: "text"
},
"asdf/zxcv/yuio": {
id: "asdf/zxcv/yuio",
expect: "yes",
question: "Do you like videogames?",
type: "text"
},
"asdf/dfgh": {
id: "asdf/dfgh",
expect: 21,
question: "Where do you live?",
type: "text"
},
"asdf/dfgh/fghj": {
id: "asdf/dfgh/fghj",
expect: "Boston",
question: "What's the weather?",
type: "text"
},
qwer: {
id: "qwer",
question: "What is your name?",
type: "text"
},
"qwer/asdf": {
id: "qwer/asdf",
expect: "David",
question: "What is your surname",
type: "text"
}
};
// We use a symbol to allow fast lookups while still having a resulting array without it
const lookup = Symbol();
const root = { [lookup]: {}, sub: [] };
// As the ids are part of the values itself, we can ignore the objects keys and directly iterate the values
for(const el of Object.values(start)) {
// Now we traverse down the nested lookup tree
let parent = root;
for(const part of el.id.split("/")) {
// If a certain path doesnt exist yet, set it up
if(!parent[lookup][part])
parent.sub.push(parent[lookup][part] = { [lookup]: {}, sub: [] });
// Dive deeper
parent = parent[lookup][part];
}
// We reached the node were the data belongs, so just assign it here:
Object.assign(parent, el);
}
// you could also get it as an array with root.sub
console.log(root[lookup]);