簡體   English   中英

從遞歸 function 構建嵌套的 object 數組

[英]Build nested object array from recursive function

我將如何利用我的 getChildren() function 創建一個更大的 function 它采用我的兩個主要 arrays objsobjRefs並輸出一個 objs 數組來證明它們的父/子關系。

這是兩個主要數據 arrays

const objs = [
    { name: "Kevin", age: 5, id: 1 },
    { name: "Matt", age: 53, id: 5 },
    { name: "Marry", age: 30, id: 2 },
    { name: "Leslie", age: 21, id: 3 },
    { name: "Sarah", age: 46, id: 4 },
    { name: "Heather", age: 37, id: 6 },
    { name: "Cory", age: 19, id: 7 },
]

const objRefs = [
    { parent_id: 5, obj_id: 7 }, // cory child of matt
    { parent_id: null, obj_id: 6 }, // matt root
    { parent_id: null, obj_id: 4 }, // sarah root
    { parent_id: null, obj_id: 5 }, // heather root
    { parent_id: 5, obj_id: 3 }, // leslie child of matt
    { parent_id: 4, obj_id: 2 }, // mary child of sarah
    { parent_id: 3, obj_id: 1 }, // kevin child of leslie
]

我的目標是運行一個名為getFamilyTree()的 function,它將返回給我這個...

const tree = [
    {
        id: 5,
        name: "Matt",
        age: 53,
        children:[ 
            {
                id: 3,
                name: "Leslie",
                age: 21,
                children:[ 
                    {
                        id: 1,
                        name: "Kevin",
                        age: 5,
                        children:[ ]
                    }
                ]
            },
            {
                id: 7,
                name: "Cory",
                age: 19,
                children:[ ]
            }
        ]
    },
    {
        id: 6,
        name: "Heather",
        age: 37,
        children:[ ]
    },
    {
        id: 4,
        name: "Sarah",
        age: 46,
        children:[ 
            {
                id: 2,
                name: "Marry",
                age: 30,
                children:[ ]
            }
        ]
    }
]

我有一個 function 返回給定父節點 ID 的所有子節點,但我不確定如何構建 function 以返回整個樹,就像我的示例一樣。

function getChildren(parent_id) {
    let children = []
    for (var i = 0; i < objRefs.length; i++) {
        const ref = objRefs[i]
        if (ref.parent_id === parent_id) {
            const obj = objs.find(obj => {
                return obj.id === ref.obj_id
            })
            children.push(obj)
        }
    }
    return children
}

function getFamilyTree() {
    let result = []
    ... // build recursive family tree
    return result 
}

我認為您甚至不需要getChildren function 來實際構建您的樹。 改用地圖可能會有用:

 const objs = [ { name: "Kevin", age: 5, id: 1 }, { name: "Matt", age: 53, id: 5 }, { name: "Marry", age: 30, id: 2 }, { name: "Leslie", age: 21, id: 3 }, { name: "Sarah", age: 46, id: 4 }, { name: "Heather", age: 37, id: 6 }, { name: "Cory", age: 19, id: 7 }, ] const objRefs = [ { parent_id: 5, obj_id: 7 }, // cory child of matt { parent_id: null, obj_id: 6 }, // matt root { parent_id: null, obj_id: 4 }, // sarah root { parent_id: null, obj_id: 5 }, // heather root { parent_id: 5, obj_id: 3 }, // leslie child of matt { parent_id: 4, obj_id: 2 }, // mary child of sarah { parent_id: 3, obj_id: 1 }, // kevin child of leslie ] function getFamillyTree(){ const nodes = new Map() // Preparing the data nodes objs.forEach(elt => nodes.set(elt.id, {...elt, children: [], root: false})) // Linking the nodes to make the parent <-> children relations objRefs.filter(rel =>..rel.parent_id).forEach(rel => { const parent = nodes.get(rel.parent_id) parent.children.push(nodes.get(rel.obj_id)) }) // Marking the roots objRefs.filter(rel => rel.parent_id === null).forEach(rel => { const obj = nodes.get(rel.obj_id) obj.root = true }) return Array.from(nodes.values()).filter(obj => obj.root) } document,write(JSON,stringify(getFamillyTree(), null, 4))

編輯:這個答案可能略有偏差,因為正如尼娜在對該問題的評論中所述,OP 似乎要求一個明確的遞歸解決方案,將其留在這里以供參考。

您不需要遞歸 function 來構造它。

為了獲得合理的時間復雜度,將所有objs存儲到 Map 或其他內容(如果id是連續的,即使是數組也可以)由id鍵控。 然后,只需迭代objRefs並適當地構建關系:

 const objs = [ { name: "Kevin", age: 5, id: 1 }, { name: "Matt", age: 53, id: 5 }, { name: "Marry", age: 30, id: 2 }, { name: "Leslie", age: 21, id: 3 }, { name: "Sarah", age: 46, id: 4 }, { name: "Heather", age: 37, id: 6 }, { name: "Cory", age: 19, id: 7 }, ] const objRefs = [ { parent_id: 5, obj_id: 7 }, // cory child of matt { parent_id: null, obj_id: 6 }, // matt root { parent_id: null, obj_id: 4 }, // sarah root { parent_id: null, obj_id: 5 }, // heather root { parent_id: 5, obj_id: 3 }, // leslie child of matt { parent_id: 4, obj_id: 2 }, // mary child of sarah { parent_id: 3, obj_id: 1 }, // kevin child of leslie ] function getFamilyTree(objs, objRefs){ const tree = [] const map = new Map( objs.map(e => [e.id, {...e, children: [] }]) ) for(const {parent_id, obj_id} of objRefs){ if(parent_id === null){ tree.push(map.get(obj_id)) }else{ map.get(parent_id).children.push(map.get(obj_id)) } } return tree } const tree = getFamilyTree(objs, objRefs) console.log(tree)

您可以使用一些 object 作為人員及其關系的參考,以及 map 與他們的孩子的節點。

 const getChildren = parent => (references[parent] || []).map(id => ({...nodes[id], children: getChildren(id) })), people = [{ name: "Kevin", age: 5, id: 1 }, { name: "Matt", age: 53, id: 5 }, { name: "Marry", age: 30, id: 2 }, { name: "Leslie", age: 21, id: 3 }, { name: "Sarah", age: 46, id: 4 }, { name: "Heather", age: 37, id: 6 }, { name: "Cory", age: 19, id: 7 }], children = [{ parent_id: 5, obj_id: 7 }, { parent_id: null, obj_id: 6 }, { parent_id: null, obj_id: 4 }, { parent_id: null, obj_id: 5 }, { parent_id: 5, obj_id: 3 }, { parent_id: 4, obj_id: 2 }, { parent_id: 3, obj_id: 1 }], nodes = Object.fromEntries(people.map(o => [o.id, o])), references = children.reduce((r, { parent_id, obj_id }) => ((r[parent_id]??= []).push(obj_id), r), {}), tree = getChildren(null); console.log(tree);
 .as-console-wrapper { max-height: 100%;important: top; 0; }

一種帶有單個children循環的方法。

 const getTree = (people, children, root) => { const nodes = Object.fromEntries(people.map(o => [o.id, o])), t = {}; children.forEach(({ parent_id: p, obj_id: id }) => ((t[p]??= {}).children??= []).push(Object.assign(t[id]??= {}, nodes[id])) ); return t[root].children; }, people = [{ name: "Kevin", age: 5, id: 1 }, { name: "Matt", age: 53, id: 5 }, { name: "Marry", age: 30, id: 2 }, { name: "Leslie", age: 21, id: 3 }, { name: "Sarah", age: 46, id: 4 }, { name: "Heather", age: 37, id: 6 }, { name: "Cory", age: 19, id: 7 }], children = [{ parent_id: 5, obj_id: 7 }, { parent_id: null, obj_id: 6 }, { parent_id: null, obj_id: 4 }, { parent_id: null, obj_id: 5 }, { parent_id: 5, obj_id: 3 }, { parent_id: 4, obj_id: 2 }, { parent_id: 3, obj_id: 1 }], tree = getTree(people, children, null); console.log(tree);
 .as-console-wrapper { max-height: 100%;important: top; 0; }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM