js 数组转树形菜单

572 阅读1分钟
//列表菜单
var data=[
    { id: 1, parentId: 0, note: "一级菜单-11" }, 
    { id: 2, parentId: 0, note: "一级菜单-12" },
    { id: 2, parentId: 1, note: "二级菜单-22" },
    { id: 3, parentId: 2, note: "三级菜单-33" },
    { id: 4, parentId: 2, note: "三级菜单-44" }
];
//树形菜单 
let tree = 
[{
    "id": 1,
    "parentId": 0,
    "note": "一级菜单-11",
    "chlidren": [{
        "id": 2,
        "parentId": 1,
        "note": "二级菜单-22",
        "chlidren": [{
            "id": 3,
            "parentId": 2,
            "note": "三级菜单-33"
        }, {
            "id": 4,
            "parentId": 2,
            "note": "三级菜单-44"
        }]
    }]
}, {
    "id": 2,
    "parentId": 0,
    "note": "一级菜单-12"
}]

1.需要把数组列表转树形菜单

性能较优

//通过对象引用的特点 只改变父级关系
function listToTree(list) {
    let tree = []
    const mapObj = {}
    list.forEach(o => {
        mapObj[o.id] = o
    });
    list.forEach(o => {
        if (o.parentId == 0) {//如果是根节点 直接加入根集合
            tree.push(o)
        } else {
          const parentObj =  mapObj[o.parentId]
          if(!parentObj.chlidren) {
            parentObj.chlidren = [o]
          } else {
            parentObj.chlidren.push(o)
          }
        }
    })
    return tree
}

console.log(JSON.stringify(listToTree(data,0)))


//使用reduce获取集合对象
function listToTree(list) {
    let tree = [] 
    const map = list.reduce( (acc,val) => {
        acc[val.id] = val
        return acc
    },{})  
    list.forEach(o => {
        if (o.parentId == 0) {//如果是根节点 直接加入根集合
            tree.push(o)
        } else { 
          const parentObj =  map[o.parentId]
          if(!parentObj.chlidren) {
            parentObj.chlidren = [o]
          } else {
            parentObj.chlidren.push(o)
          }
        }
    })
    return tree
}
console.log(JSON.stringify(listToTree(data,0)))

递归的方式 效率较低

function listToTree2(list,parentId) {
    let tmpList = []
    list.forEach(o => {
        if(o.parentId == parentId) {
            tmpList.push(o)
            const list2 = listToTree2(list,o.id)
            if(list2) {
                o.chlidren = list2
            }
        }
    });
    return tmpList
}
 
console.log(JSON.stringify(listToTree2(data,0)))

2.树形菜单转数组列表 (数据扁平化)

//树形转列表 递归
function treeToList(list,parentId) { 
    let tmpList = [] 
    if (list) {
        list.forEach(o => {
            tmpList.push({id:o.id,note:o.note,parentId:parentId})
            tmpList = tmpList.concat(treeToList(o.chlidren,o.id)) 
        });
    }
    return tmpList
}
console.log(JSON.stringify(treeToList(tree,0)))