前端手写: 数组转树

8 阅读1分钟

let list = [
  { "id": 12, "parent_id": 1, "name": "朝阳区" },
  { "id": 241, "parent_id": 24, "name": "田林街道" },
  { "id": 31, "parent_id": 3, "name": "广州市" },
  { "id": 13, "parent_id": 1, "name": "昌平区" },
  { "id": 2421, "parent_id": 242, "name": "上海科技绿洲" },
  { "id": 21, "parent_id": 2, "name": "静安区" },
  { "id": 242, "parent_id": 24, "name": "漕河泾街道" },
  { "id": 22, "parent_id": 2, "name": "黄浦区" },
  { "id": 11, "parent_id": 1, "name": "顺义区" },
  { "id": 2, "parent_id": 0, "name": "上海市" },
  { "id": 24, "parent_id": 2, "name": "徐汇区" },
  { "id": 1, "parent_id": 0, "name": "北京市" },
  { "id": 2422, "parent_id": 242, "name": "漕河泾开发区" },
  { "id": 32, "parent_id": 3, "name": "深圳市" },
  { "id": 33, "parent_id": 3, "name": "东莞市" },
  { "id": 3, "parent_id": 0, "name": "广东省" }
]
// 使用递归 先用filter筛选出同一级别的,再map修改每一个下children
function arrToTree(list, rootId) {
  // 
  return list
    .filter(item => item.parent_id === rootId)
    .map(item => ({ ...item, children: arrToTree(list, item.id) }))

}
console.log('递归 tree数据::', arrToTree(list, 0));

// 使用map 两次循环
// 定义一个map结果, 把所以数据存入,
// 循环每一项,把每项找到他的上一级数据,把本条数据插入上级数据中
// 如果他的父节点是跟节点直接存入新数组中

function arrToTree1(list, rootId) {
  let map = new Map();
  let tree = [];
  list.forEach(item => {
    map.set(item.id, { ...item, children: [] })
  })
  list.forEach(item => {
    const parent = map.get(item.parent_id);
    const node = map.get(item.id)
    if (parent) {
      parent.children.push(node);
    } else if (item.parent_id === rootId) {
      tree.push(node)
    }

  })

  return tree;
}

console.log('map 树:', arrToTree1(list, 0))