javascript将扁平的数据转为树形结构的几种方法

扁平菜单示例以下:
var menu_list = [{算法

id: '1',
  menu_name: '设置',
  menu_url: 'setting',
  parent_id: 0
}, {
  id: '1-1',
  menu_name: '权限设置',
  menu_url: 'setting.permission',
  parent_id: '1'
}, {
  id: '1-1-1',
  menu_name: '用户管理列表',
  menu_url: 'setting.permission.user_list',
  parent_id: '1-1'
}, {
  id: '1-1-2',
  menu_name: '用户管理新增',
  menu_url: 'setting.permission.user_add',
  parent_id: '1-1'
}, {
  id: '1-1-3',
  menu_name: '角色管理列表',
  menu_url: 'setting.permission.role_list',
  parent_id: '1-1'
}, {
  id: '1-1-4',
  menu_name: '角色管理新增',
  menu_url: 'setting.permission.role_add',
  parent_id: '1-1'
}, {
  id: '1-2',
  menu_name: '菜单设置',
  menu_url: 'setting.menu',
  parent_id: '1'
}, {
  id: '1-2-1',
  menu_name: '菜单列表',
  menu_url: 'setting.menu.menu_list',
  parent_id: '1-2'
}, {
  id: '1-2-2',
  menu_name: '菜单添加',
  menu_url: 'setting.menu.menu_add',
  parent_id: '1-2'
}, {
  id: '2',
  menu_name: '订单',
  menu_url: 'order',
  parent_id: 0
}, {
  id: '2-1',
  menu_name: '报单审核',
  menu_url: 'order.orderreview',
  parent_id: '2'
}, {
  id: '2-2',
  menu_name: '退款管理',
  menu_url: 'order.refundmanagement',
  parent_id: '2'
}, {
  id: '2-3',
  menu_name: '实物订单',
  menu_url: 'order.realorder',
  parent_id: '2'
}, {
  id: '2-1-1',
  menu_name: '所有报单',
  menu_url: 'order.orderreview.all',
  parent_id: '2-1'
}, {
  id: '2-2-1',
  menu_name: '全部记录',
  menu_url: 'order.refundmanagement.all',
  parent_id: '2-2'
}, {
  id: '2-2-2',
  menu_name: '待处理',
  menu_url: 'order.refundmanagement.wait',
  parent_id: '2-2'
}, {
  id: '2-2-3',
  menu_name: '退款缘由',
  menu_url: 'order.refundmanagement.result',
  parent_id: '2-2'
}, {
  id: '2-3-1',
  menu_name: '实物订单管理',
  menu_url: 'order.realorder.list',
  parent_id: '2-3'
}, {
  id: '3',
  menu_name: '商品',
  menu_url: 'commodity',
  parent_id: 0
}, {
  id: '3-1',
  menu_name: '分类管理',
  menu_url: 'commodity.classifieldmanagement',
  parent_id: '3'
}, {
  id: '3-1-1',
  menu_name: '管理',
  menu_url: 'commodity.classifieldmanagement.management',
  parent_id: '3-1'
}, {
  id: '3-1-2',
  menu_name: '编辑或新增',
  menu_url: 'commodity.classifieldmanagement.edit',
  parent_id: '3-1'
}, {
  id: '3-2',
  menu_name: '品牌管理',
  menu_url: 'commodity.brandmanagement',
  parent_id: '3'
}, {
  id: '3-2-1',
  menu_name: '管理',
  menu_url: 'commodity.brandmanagement.management',
  parent_id: '3-2'
}, {
  id: '3-2-2',
  menu_name: '编辑或新增',
  menu_url: 'commodity.brandmanagement.edit',
  parent_id: '3-2'
}, {
  id: '3-3',
  menu_name: '商品管理',
  menu_url: 'commodity.commoditymanagement',
  parent_id: '3'
}, {
  id: '3-3-1',
  menu_name: '管理',
  menu_url: 'commodity.commoditymanagement.management',
  parent_id: '3-3'
}, {
  id: '3-3-2',
  menu_name: '编辑或新增',
  menu_url: 'commodity.commoditymanagement.edit',
  parent_id: '3-3'
}, {
  id: '3-4',
  menu_name: '类型管理',
  menu_url: 'commodity.typeManagement',
  parent_id: '3'
}, {
  id: '3-4-1',
  menu_name: '管理',
  menu_url: 'commodity.typeManagement.management',
  parent_id: '3-4'
}, {
  id: '3-4-2',
  menu_name: '编辑或新增',
  menu_url: 'commodity.typeManagement.edit',
  parent_id: '3-4'
}];

一、 O(n)级算法数组

function buildTree(list){
    let temp = {};
    let tree = {};
    for(let i in list){
        temp[list[i].id] = list[i];
    }
    for(let i in temp){
        if(temp[i].parent_id) {
            if(!temp[temp[i].parent_id].children) {
                temp[temp[i].parent_id].children = new Object();
            }
            temp[temp[i].parent_id].children[temp[i].id] = temp[i];
        } else {
            tree[temp[i].id] =  temp[i];
        }
    }
    return tree;
}

二、let array = [
{ui

id: 1,
parent_id: 0,
name: "四川省"

},
{url

id: 2,
parent_id: 0,
name: "广东省"

},
{code

id: 3,
parent_id: 0,
name: "江西省"

},
{对象

id: 5,
parent_id: 1,
name: "成都市"

},
{it

id: 6,
parent_id: 5,
name: "锦江区"

},
{io

id: 7,
parent_id: 6,
name: "九眼桥"

},
{console

id: 8,
parent_id: 6,
name: "兰桂坊"

},
{function

id: 9,
parent_id: 2,
name: "东莞市"

},
{

id: 10,
parent_id: 9,
name: "长安镇"

},
{

id: 11,
parent_id: 3,
name: "南昌市"

}
]

将扁平的数据转为树形结构的几种方法
function listToTree(list) {
  let map = {};
  list.forEach(item => {
    if (! map[item.id]) {
      map[item.id] = item;
    }
  });
 
  list.forEach(item => {
    if (item.parent_id !== 0) {
      map[item.parent_id].children ? map[item.parent_id].children.push(item) : 
      map[item.parent_id].children = [item];
    }
  });
   
  return list.filter(item => {
    if (item.parent_id === 0) {
      return item;
    }
  })
}
console.log(listToTree(array));

思路:一、先将数组中的全部元素都复制到 map 中(注意:这里是引用复制哦,这个细节很重要)
二、时候遍历 parent_id 不等于 0 的元素,根据当前item的id去和map对象中的引用id进行对比,若是一致就说明该对象就是他的children,而后判断了是否存在 children,若是不存在则直接给它赋值,不然将值 push 到 children 中。
三、过滤parentid=0的数据