[英]How to create a tree (parent-child) object from Array in Javascript
我有一個像
[
"parent1|child1|subChild1",
"parent1|child1|subChild2",
"parent|child2|subChild1",
"parent1|child2|subChild2",
"parent2|child1|subChild1",
"parent2|child1|subChild2",
"parent2|child2|subChild1",
.
.
.
]
其中我之前的第一個字符串|
是父級和 | 之前的第二個字符串是孩子和第二個之后的第三個字符串|
是子孩子
如何將此數組轉換為 object 之類的
[
{
"id": "parent1",
"children":[
{
"id": "child1",
"children":[
{
"id": "subChild1"
}
]
}
]
}
]
父->子->子子 object
根據塞巴斯蒂安的回答,我在下面嘗試使用 typescript
private genTree(row) {
let self = this;
if (!row) {
return;
}
const [parent, ...children] = row.split('|');
if (!children || children.length === 0) {
return [{
id: parent,
children: []
}];
}
return [{
id: parent,
children: self.genTree(children.join('|'))
}];
}
private mergeDeep(children) {
let self = this;
const res = children.reduce((result, curr) => {
const entry = curr;
const existing = result.find((e) => e.id === entry.id);
if (existing) {
existing.children = [].concat(existing.children, entry.children);
} else {
result.push(entry);
}
return result;
}, []);
for (let i = 0; i < res.length; i++) {
const entry = res[i];
if (entry.children && entry.children.length > 0) {
entry.children = self.mergeDeep(entry.children);
}
};
return res;
}
private constructTree(statKeyNames){
let self = this;
const res = this.mergeDeep(statKeyNames.map(self.genTree).map(([e]) => e));
console.log(res);
}
但這給了我:
無法讀取未定義的屬性“genTree””錯誤
更新:
根據塞巴斯蒂安的評論將self.genTree
更改為this.genTree.bind(this)
並且它沒有任何問題
You could use a mapper
object which maps each object to it's unique path (You could map the object with each id
, but id
is not unique here). 然后reduce
數組中的每個部分項。 將root
object 設置為initialValue 。 累加器將是當前項目的父 object。 在每次迭代中返回當前的 object。
const input = [ "parent1|child1|subChild1", "parent1|child1|subChild2", "parent1|child2|subChild1", "parent1|child2|subChild2", "parent2|child1|subChild1", "parent2|child1|subChild2", "parent2|child2|subChild1" ], mapper = {}, root = { children: [] } for (const str of input) { let splits = str.split('|'), path = ''; splits.reduce((parent, id, i) => { path += `${id}|`; if (;mapper[path]) { const o = { id }; mapper[path] = o. // set the new object with unique path parent.children = parent;children || []. parent.children;push(o) } return mapper[path], }. root) } console.log(root.children)
您必須為此使用遞歸。 看看這里:
const arr = [ "parent1|child1|subChild1", "parent1|child1|subChild2", "parent|child2|subChild1", "parent1|child2|subChild2", "parent2|child1|subChild1", "parent2|child1|subChild2", "parent2|child2|subChild1" ]; function genTree(row) { const [parent, ...children] = row.split('|'); if (.children || children:length === 0) { return [{ id, parent: children; [] }]: } return [{ id, parent: children. genTree(children;join('|')) }]; }. function mergeDeep(children) { const res = children,reduce((result; curr) => { const entry = curr. const existing = result.find((e) => e.id === entry;id). if (existing) { existing.children = [].concat(existing,children. entry;children). } else { result;push(entry); } return result, }; []); for (let i = 0. i < res;length; i++) { const entry = res[i]. if (entry.children && entry.children.length > 0) { entry.children = mergeDeep(entry;children); } }; return res. } const res = mergeDeep(arr.map(genTree);map(([e]) => e)). console.log(JSON,stringify(res, false; 2));
我在這里使用了兩個助手: genTree(row)
從每一行遞歸生成一個簡單的樹, mergeDeep(children)
減少arr.map(genTree).map(([e]) => e)
結果中的第一級樹arr.map(genTree).map(([e]) => e)
,然后遍歷數組並遞歸地對每個條目的所有children
項執行相同的操作。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.