JS 树形数据结构的转化

1.根据id和pid去格式化树形结构,把数据给格式化成嵌套型

平常在使用antd的tree或者elementUI的tree去开发项目的时候,要求向这个组件中传递的数据都是格式化好的,有嵌套层级的数组,这种情况下就需要我们自行封装方法去组装数据结构,具体的代码如下:

// 格式化树数据
function toTreeData(data) {
  const pos = {}
  const tree = []
  let i = 0
  while(data.length != 0) {
    if(data[i].pid == null) {
      tree.push({
        id: data[i].id,
        pid: null,
        key: data[i].id,
        title: data[i].text,
        children: []
      })
      pos[data[i].id] = [ tree.length - 1 ]
      data.splice(i, 1)
      i--
    } else {
      const posArr = pos[data[i].pid]
      if(posArr != undefined) {
        let obj = tree[posArr[0]]
        for(let j = 1; j < posArr.length; j++) {
          obj = obj.children[posArr[j]]
        }
        obj.children.push({
          id: data[i].id,
          pid: data[i].pid,
          key: data[i].id,
          title: data[i].text,
          children: []
        })
        pos[data[i].id] = posArr.concat([ obj.children.length - 1 ])
        data.splice(i, 1)
        i--
      }
    }
    i++
    if(i > data.length - 1) {
      i = 0
    }
  }
  return tree
}

看一下在antd的tree组件中的实例吧:

import React, { useState, useEffect } from 'react'
import { Button, Tree } from 'antd'

// 格式化树数据
function toTreeData(data) {
  const pos = {}
  const tree = []
  let i = 0
  while(data.length != 0) {
    if(data[i].pid == null) {
      tree.push({
        id: data[i].id,
        pid: null,
        key: data[i].id,
        title: data[i].text,
        children: []
      })
      pos[data[i].id] = [ tree.length - 1 ]
      data.splice(i, 1)
      i--
    } else {
      const posArr = pos[data[i].pid]
      if(posArr != undefined) {
        let obj = tree[posArr[0]]
        for(let j = 1; j < posArr.length; j++) {
          obj = obj.children[posArr[j]]
        }
        obj.children.push({
          id: data[i].id,
          pid: data[i].pid,
          key: data[i].id,
          title: data[i].text,
          children: []
        })
        pos[data[i].id] = posArr.concat([ obj.children.length - 1 ])
        data.splice(i, 1)
        i--
      }
    }
    i++
    if(i > data.length - 1) {
      i = 0
    }
  }
  return tree
}

function Myrefs() {
  const [ treeData, setTree ] = useState([])

    //未格式化之前的数组,就是一个普通的数组
  const init = [
    {
      id: 1,
      pid: null,
      text: '1-1111',
    },
    {
      id: 2,
      pid: 1,
      text: '2-1111',
    },
    {
      id: 3,
      pid: 1,
      text: '9-1111',
    },
    {
      id: 4,
      pid: 2,
      text: '8-1111',
    },
  ]

  useEffect(() => {
    const arr = toTreeData(init)
    console.log(arr)
//将格式化之后的数据扔到tree这个组件中
    setTree(arr)
  }, [])

  return (
    <Tree treeData={treeData} />
  )
}

export default Myrefs

页面实现的效果如下图:

 

2.把嵌套型给格式化成扁平型数据结构

具体实现的代码如下:

// 嵌套格式转扁平格式
function dataToFlatten(data) {
  let arr = []
  data.forEach((item) => {
    arr.push({
      id: item.id,
      pid: item.pid,
      title: item.title,
    })
    if (item.children?.length) {
      arr = arr.concat(dataToFlatten(item.children))
    }
  })
  return arr
}

const arr = [
    {
        "id":1,
        "pid":null,
        "key":1,
        "title":"1-1111",
        "children":[
            {
                "id":2,
                "pid":1,
                "key":2,
                "title":"2-1111",
                "children":[
                    {
                        "id":4,
                        "pid":2,
                        "key":4,
                        "title":"8-1111",
                        "children":[

                        ]
                    }
                ]
            },
            {
                "id":3,
                "pid":1,
                "key":3,
                "title":"9-1111",
                "children":[

                ]
            }
        ]
    }
]

const arr2 = dataToFlatten(arr)

//这个arr2就是扁平化之后的数据了
console.log(arr2)

至此就分享完毕了,对您有帮助的话,就点赞吧!或者在下方参与讨论吧!

 

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值