扁平数组与树形数组的相互转换(详例 & 代码)

本文介绍了在开发中如何将带有parentID的扁平数组转换为树形数组,以及从树形数组转换回扁平数组的方法。提供了JavaScript代码示例,包括使用forEach和filter函数进行递归处理,适用于数据结构转换场景。
摘要由CSDN通过智能技术生成

        笔者在写树形下拉框组件时需要将扁平数组转换为树形数组,因此便想做一期两种数组相互转换的内容,如有错误恳请指正。

1. 扁平数组 >>> 树形数组

        在开发中,获取的数据多数情况下是带有 parent ID 的扁平数组,而我们需要将其转换为树形数组。扁平数组的格式如下所示:扁平数组中,每项主要由 id name 组成,通过 pid 指向对应的父节点。而像“中国”这样的树节点, pid 则为空。

        转换为树形数组的思想是:遍历扁平数组中的每项数据,根据 pid 判断当前节点的父节点和子节点。

源码展示:

        // .js
        const data = [
            // 每项主要由id和name组成,而pid指向其父节点的id
            // 如果是树节点则对应的pid为空
            { id: '01', name: '中国', pid: ''},
            { id: '02', name: '北京市', pid: '01'},
            { id: '03', name: '海淀区', pid: '02'},
            { id: '04', name: '丰台区', pid: '02'},
            { id: '05', name: '朝阳区', pid: '02'},
            { id: '06', name: '重庆市', pid: '01'},
            { id: '07', name: '渝中区', pid: '06'},
            { id: '08', name: '江北区', pid: '06'},
            { id: '09', name: '四川省', pid: '01'},
            { id: '10', name: '成都市', pid: '09'},
            { id: '11', name: '成华区', pid: '10'},
            { id: '12', name: '武侯区', pid: '10'}
        ];

        function transNormalToTree(array) {
            let  result = [] //最终存储的结果

            // 对数组中的每个对象进行遍历
            array.forEach( item => {
                // 判断当前节点是否为根节点,如果是则push
                if (!item.pid) {
                    result.push(item)
                }

                // 将所有pid等于当前id的对象储存在children数组中
                let childArray = array.filter(data => data.pid === item.id)

                // 判断当前节点是否为叶节点,如果是则退出
                if (!childArray.length) {
                    return  
                }

                // 将符合条件的子数组赋值给当前项的child属性
                item.child = childArray
            })
            return result
        }

        console.log(transNormalToTree(data))

2. 树形数组 >>> 扁平数组

        虽然多数时候需要我们将扁平数组转换为树形数组,但掌握反向转换的方法也很重要。我这里直接将我另一篇文章里的内容贴出来:

        树形数组的就是扁平数组反过来的结构,子节点包含在父节点的children属性中。

        转换方法有两个参数,一是源数组,二是存放结果的空数组。对源数组进行 forEach 遍历循环:将当前元素 push 进结果数组。其中结果数组的 label 是源数组的 label,value 是源数组的 id 。然后再对当前元素进行判断:如果其有 children 节点,则再次执行 optionData 方法,而参数则是该元素的 children 节点和第一次迭代的 result 。这样直到最后一个元素判断后,返回 result

感兴趣的朋友可以看一下这篇文章:组件Element-UI 2实现树形下拉选择框

 源码展示:

    //  Vue .js
    cityData: [{
        id: 1,
        label: '重庆',
        children: [{
          id: 2,
          label: '渝北区'
        }]
      }, {
        id: 3,
        label: '北京',
        children: [
          { id: 4, label: '海淀区' },
          { id: 5, label: '朝阳区' }
        ]
      }, {
        id: 6,
        label: '四川',
        children: [
          {
            id: 7,
            label: '成都',
            children: [
              { id: '8', label: '成华区' }
            ]
          }
        ]
      }]
    // .js
    optionData(array, result=[]) {
      array.forEach(item => {
        result.push({label:item.label,value:item.id})
        if (item.children && item.children.length !== 0) { 
          this.optionData(item.children, result)
        } 
      })
      return JSON.parse(JSON.stringify(result))
    },
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值