[英]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.