簡體   English   中英

如何將一維數組變成二維數組,使父母可以深入兩個以上的層次?

[英]How to turn a one dimensional array into a two dimensional one where the parents can go more than two levels deep?

我有一個一維對象數組,每個對象都有一個ID和其父代的ID。 在初始數組中,我每個元素最多可以有一個孩子。 因此,如果數組如下所示:

{id: 3, parent: 5},
{id: 5, parent: null},
{id: 6, parent: 3},
{id: 1, parent: null},
{id: 4, parent: 7},
{id: 2, parent: 1},
{id: 7, parent: 2}

我需要它看起來像這樣:

{id: 5, parent: null, children: [
  {id: 3, parent: 5},
  {id: 6, parent: 3}
]},
{id: 1, parent: null, children: [
  {id: 2, parent: 1},
  {id: 7, parent: 2},
  {id: 4, parent: 7},
]}

我認為我這樣做的方式使用了太多的循環。 有沒有更好的辦法?

 let items = [ {id: 3, parent: 5}, {id: 5, parent: null}, {id: 6, parent: 3}, {id: 1, parent: null}, {id: 4, parent: 7}, {id: 2, parent: 1}, {id: 7, parent: 2} ]; let itemsNew = []; items = items.map(function(x){ return {id: x.id, parent: x.parent, children: []}; }); // new array with parents only for(let i=items.length-1; i>=0; i--){ if(items[i].parent == null){ itemsNew.push(items[i]); items.splice(i, 1); } } for(let i=0; i<itemsNew.length; i++){ let childIndexes = findChildAll(itemsNew[i].id); // sort the indexes so splicing the array wont misplace them childIndexes.sort(function(a,b){ return ba; }); for(let j=0; j<childIndexes.length; j++){ itemsNew[i].children.push(items[childIndexes[j]]); items.splice(childIndexes[j], 1); } } // returns an array of indexes of all the element's children and their children function findChildAll(parentId){ for(let i=0; i<items.length; i++){ if(items[i].parent == parentId){ let resultArray = findChildAll(items[i].id); // is the result as an array add it to the index if(resultArray) return [i].concat(resultArray); // otherwise return just this index return [i]; } } } console.log(itemsNew); 

您可以通過使用filter大大簡化它:

  for(const item of items) 
    item.children = items.filter(child => child.parent === item.id);

 const parents = items.filter(item => !item.parent);

或者,如果有很多節點,使用Map可能對性能有好處:

 const itemsByID = new Map(items.map(item => [item.id, item]));

 const parents = [];

 for(const item of items) {
   if(item.parent) {
     const parent = itemsByID[item.parent];
     if(!parent.children) parent.children = [];
     parent.children.push(item);
  } else parents.push(item);
}

如果數組變大,則查找子項可能會很慢,因為該函數始終在整個數組中搜索

const withParent = items.filter((item) => item.parent !== null);
const getDeepIdsWithId = (id) => {
    const result = [];
    while (true) {
        const i = withParent.find((item) => item.parent === id);
        if (!i) {
            break;
        }
        id = i.id;
        result.push(i);
    }
    return result;
};
const parent = items.filter((item) => item.parent === null).map((item) => ({...item, children: getDeepIdsWithId(item.id)}));

我認為您可以采用類似以下的遞歸方法:

const array1 = [{id: 3, parent: 5},
    {id: 5, parent: null},
    {id: 6, parent: 3},
    {id: 1, parent: null},
    {id: 4, parent: 7},
    {id: 2, parent: 1},
    {id: 7, parent: 2}];

const getChild = (origi, fathers) => 
    origi.filter(
        originEle => originEle.parent && fathers.some(f => f.id === originEle.parent)
    )

const getChildren = (originArray, fathers) => {
    let childs = getChild(originArray, fathers);

    let continueFetching = childs && childs.length > 0;

    while (continueFetching) {
        const moreChilds = getChild(originArray, childs)
            .filter(m => !childs.some(c => c.id === m.id))

        if (
            moreChilds && 
            moreChilds.length > 0
        ) {
            childs = childs.concat(moreChilds);
            continueFetching = true;
        } else {
            continueFetching = false;
        }
    }

    return childs;
}

const result = array1
    .filter(
        a1 => !a1.parent
    )
    .map(
        aFather => ({
            id: aFather.id,
            parent: null,
            children: getChildren(array1, [aFather])
        })
    )

暫無
暫無

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

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