In front end development, we sometimes have a situation where the back end gives us a tiled set of data. What we need to render is a tree structure, so how do we convert it?

[{id:"01".pid:""."name":"Wang" },
   {id:".".pid:"01"."name":"Zhang" },
   {id:"3".pid:"01"."name":"Wang" },
   {id:"04".pid:""."name":"老李" },
   {id:"5".pid:"04"."name":"Yellow" },
   {id:"6".pid:"04"."name":"Small beautiful"}]Copy the code

You can kind of get a sense of the hierarchy from the ID and PID above, but the data is a tiled data, which is not good for rendering so we can encapsulate a tool, transform that data, transform it into a tree structure

Recursion

The recursive method is relatively convenient, but it may not be particularly easy for some programmers to understand, so let’s break it down a little bit. First we declare a function, and then we pass in two values

 list // The first is the array you need to convert
 pid // The second is the value of the first level of the data you need to convert
Copy the code

Pid =” means that when you call a function and you don’t pass a value, that “” is your default value, you can change that and then we’ll filter out all the data from pid=””

 function toRee (list,pid = ' ' ){
   let newList = list.filter(it= >it.pid === pid)
    return newList 
  }
Copy the code

And when we do that, we have twopid=''Array of objectsWe then iterate over the array (anything that loops through the array and returns the value, such as a map() method) and add one to the two objectschildrenattribute

And set its value equal to the return value of the called function

 function toRee (list,pid = ' ' ){
   let newList= list.filter(it= >it.pid === pid)
    newList.forEach(it= > it.children = toRee(list,it.id) )
    return newList 
  }
Copy the code

This return value is the key. It’s an array and it’s a PID is equal to the value of every object ID in the newList and so it’s a recursion, until the newList is no longer an array

The deeper the data is, the more times the recursive function is used, compared to the non-recursive function below

Second, non-recursive method

What I’m writing here is a non-recursive way of converting data

function totree(arr) {
  const newArr = []
  const map = {}
Copy the code

Declare variables first

 arr.forEach(item= > {
   if(! item.children) item.children = []; Check whether the data has sub-levels. If no, add sub-levels map[item.id] = item// Add the mapping
 })
Copy the code

Then through the loop to determine whether each data has child attributes, add child attributes, the value is an empty array

This is where the data is mapped

Get all the data ids out, and then use the form of key-value pair to generate a new object, which is convenient for us to compare later

{
 01: {id:"01".pid:""."name":"Wang" },
 02: {id:".".pid:"01"."name":"Zhang" },
 03: {id:"3".pid:"01"."name":"Wang" },
 04: {id:"04".pid:""."name":"老李" },
 05: {id:"5".pid:"04"."name":"Yellow" },
 06: {id:"6".pid:"5"."name":"Small beautiful"}}Copy the code

Finally, the loop is repeated to add all data with PID values to the children of the object mapped with PID id

 arr.forEach(item= > {
   if (map[item.pid]) {
     map[item.pid].children.push(item)
   } else {
     newArr.push(item)
   }
 })
 return newArr
}
export default totree
Copy the code

This is all done, just return newArr

If the superior and subordinate data is different, modify the corresponding data inside the complete code as follows

function totree(arr) {
  const newArr = []
  const map = {}
  arr.forEach(item= > {
    if(! item.children) item.children = []; Check whether the data has sub-levels. If no, add sub-levels map[item.id] = item// Add the mapping
  })
  arr.forEach(item= > {
    if (map[item.pid]) {
      map[item.pid].children.push(item)
    } else {
      newArr.push(item)
    }
  })
  return newArr
}
export default totree
Copy the code

Please give me a thumbs up