这是示例数据(MenuModel数组);
this.menuItems = [
{Id:1, itemName:'test-item1'},
{Id:2, itemName:'test-item2'},
{Id:3, itemName:'test-item3'},
{Id:4, itemName:'test-item4',parentId:1},
{Id:5, itemName:'test-item5',parentId:2},
{Id:6, itemName:'test-item6',parentId:1},
{Id:7, itemName:'test-item7',parentId:6}
];
MenuModel的定义:
export interface IMenuModel{
Id:number
itemName:string;
parentId?:number;
childItems?:IMenuModel[];
}
代码如下
var tempItems = this.menuItems;
var itemsConstructed: IMenuModel[] = [];
tempItems.map((item: IMenuModel, i: number) => {
var newItem: IMenuModel = { Id: item.Id, itemName: item.itemName, parentId: item.parentId, childItems: [] };
var isInList: boolean = false;
itemsConstructed.map((item_: IMenuModel) => {
if (item_.Id == newItem.parentId) {
item_.childItems ? item_.childItems.push(newItem) : [newItem];
isInList = true;
}
});
if (!isInList) {
itemsConstructed.push(newItem);
}
});
它适用于一步深,但不能放置" test-item7"因为它的父项(test-item6)也是" item1"的子项。所以我需要递归地做。我怎样才能做到这一点?
答案 0 :(得分:1)
由于itemsConstructed
不是列表而是树,因此您应该使用DFS。
function search(items:IMenuModel[],id:number):IMenuModel{
for(let i=0; i<items.length; i++){
if(items[i].Id==id){
return items[i];
}else{
if(items[i].childItems && items[i].childItems.lenght>0){
let temp = search(items[i].childItems, id);
if(temp==null){
continue;
}else{
return temp;
}
}
}
}
return null;
}
var tempItems = this.menuItems;
var itemsConstructed: IMenuModel[]=[];
tempItems.map((item:IMenuModel, i:number)=>{
var newItem:IMenuModel={ Id:item.Id, itemName:item.itemName, parentId:item.parentId, childItems:[] };
var isInList:boolean = false;
if(newItem.parentId==null){//doesn't have parentId
itemsConstructed.push(newItem);
return;
}
var parentItem=search(itemsConstructed,item.parentId);
if(parentItem==null){//doesn't exist
itemsConstructed.push(newItem);
}else{//exist in list
item_.childItems?item_.childItems.push(newItem):[newItem];
}
});
有关DFS和Tree_traversal的更多信息。