[前端攻坚]:数组转树与树转数组的方法


theme: smartblue
highlight: foundation

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第14天,点击查看活动详情

总结一些日常需要用到的一些api,也是在一些面试中会经常出现的题目,今天分享的是数组转树和树转数组的方法, 同时文章也被收录到我的《JS基础》专栏中,欢迎大家点赞收藏加关注。

开发中经常会遇到后端没有及时的处理好数据的格式问题,如果需要处理一些树形的数据,而后端返回的是一些扁平化的数组数据的话,掌握数组转树的方法,通过自己对数据的处理也能将扁平化的数据转化为树形结构的数据,数据的转换前端和后端做都是一样的,接下来一起看下结构转换的问题以及如何处理。同时提高自己的手写能力。

扁平化数组数据的结构

image.png

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": "广东省" }
]

树形数据的结构

转换为树形结构后整个数据的内容也就更加清晰了,并且某些ui组件可能会用到对应的结构类型的数据

image.png

数组转树结构

数组转树的过程总共分为几步:

  1. 将数组转成map结构,这一步主要是方便后面子寻父的操作
  2. 再次循环数组
  3. 子元素归类到父元素中
  4. 推出父元素到新数组
function fn(list){
    let obj = {}
    let res = []
    for(let item of list){
        obj[item.id] = item
    }
    for(let item of list){
        if(obj[item.parent_id]){
            (obj[item.parent_id].children || (obj[item.parent_id].children = [])).push(item)
        }else{
            res.push(item)
        }
    }
    return res
}
console.log(fn(list))

树转数组结构

树转数组也分为几个步骤,主要是用到unshift和concat两个方法

  1. 循环树 最开始取的是父数据,判断时候存在子数据,有子数据concat到要循环的树后面
  2. 删除父数据中的children,将数据传入到新数组中
  3. 继续循环树,循环完父节点,后续子节点都会跳过children的判断,并且全部push到新数组中
let list1 = [{ "id": 2, "parent_id": 0, "name": "上海市", "children": [{ "id": 21, "parent_id": 2, "name": "静安区" }, { "id": 22, "parent_id": 2, "name": "黄浦区" }, { "id": 24, "parent_id": 2, "name": "徐汇区", "children": [{ "id": 241, "parent_id": 24, "name": "田林街道" }, { "id": 242, "parent_id": 24, "name": "漕河泾街道", "children": [{ "id": 2421, "parent_id": 242, "name": "上海科技绿洲" }, { "id": 2422, "parent_id": 242, "name": "漕河泾开发区" }] }] }] }, { "id": 1, "parent_id": 0, "name": "北京市", "children": [{ "id": 12, "parent_id": 1, "name": "朝阳区" }, { "id": 13, "parent_id": 1, "name": "昌平区" }, { "id": 11, "parent_id": 1, "name": "顺义区" }] }, { "id": 3, "parent_id": 0, "name": "广东省", "children": [{ "id": 31, "parent_id": 3, "name": "广州市" }, { "id": 32, "parent_id": 3, "name": "深圳市" }, { "id": 33, "parent_id": 3, "name": "东莞市" }] }];
function toarr(list){
    let arr = []
    let a = [].concat(list)
    while(a.length>0){
        let first = a.unshift()
        if(first.children){
            a = a.concat(first.children)
            delete first.children
        }
        arr.push(first)
    }
    return arr
}
console.log(list1)
© 版权声明
THE END
喜欢就支持一下吧
点赞5 分享
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情代码图片

    暂无评论内容