How to make this data object hierarchical

const tableData = [
  {
    id: 1, // id
    parentId: 0, // id
    name: "",
    parentName: null // 
  },
  {
    id: 2,
    parentId: 1,
    name: "",
    parentName: ""
  },
  {
    id: 3,
    parentId: 2,
    name: "",
    parentName: ""
  },
  {
    id: 4,
    parentId: 3,
    name: "",
    parentName: ""
  },
  {
    id: 5,
    parentId: 4,
    name: "",
    parentName: ""
  },
  {
    id: 6,
    parentId: 0,
    name: "",
    parentName: ""
  },
  {
    id: 7,
    parentId: 6,
    name: "",
    parentName: ""
  }
]

how to make this data

[
{id: 1,parentId:0,children:[{id:2,parentId: 1,chlidren: [...]}]}
]
Aug.27,2021

for (var i= tableData.length-2; i>=1; i--){
    tableData[i-1].children = tableData[i];
}
console.log(tableData[0]);

I haven't thought of a better

yet.

someone in the comments gave the following answer:

for (var i= tableData.length-1; i>0; i--){
    tableData[i-1].children = [tableData.pop()];
}
console.log(tableData);

tell me what you think.

set two variables, obj= {}, arr= [] .

make a deep copy of tableData , which is called newTableData .

Loop through newTableData , add the children attribute to each object in newTableData , and then assign it to obj , taking the object's id as key , and taking the object as value , similar to the following:

obj = {
    1: {
        id: 1,
        parentId: 0,
        name: "",
        children: []
    },
    2: {
        id: 2,
        parentId: 1,
        name: "",
        children: []
    }
}

iterate through newTableData again. If newTableData.parentId = 0 , it is considered to be a first-class node and added to arr :

arr.push(newTableData[i])

if newTabledata [I] .parentId! = = 0 and obj [newTabledata [I] .parentId] exists:

obj[newTableData[i].parentId].children.push(newTableData[i])

because the object is a reference type, the data in arr and obj is actually a copy! Make changes on obj , and Synchronize will also exist on arr .

To put it bluntly, all the data in newTableData is saved as array and object , which is actually a leveled array.


let handleTableData = data => {
  // 
  let sortData = data.sort((a, b) => {
    return a.parentId - b.parentId
  })

  // id
  let topParentId = sortData[0].parentId

  // 
  let loop = (arr, obj) => {
    arr.map((v, i) => {
      if (v.id === obj.parentId) {
        v.children.push(obj)
      } else {
        if (v.children.length) {
          loop(v.children, obj)
        }
      }
    })
  }

  return sortData.reduce((resArr, obj) => {
    obj.children = []
    if (obj.parentId === topParentId) { // 
      resArr.push(obj)
    } else {
      loop(resArr, obj)
    }
    return resArr
  }, [])
}

const tableData = [
  {
    id: 1, // id
    parentId: 0, // id
    name: "",
    parentName: null // 
  },
  {
    id: 2,
    parentId: 1,
    name: "",
    parentName: ""
  },
  {
    id: 3,
    parentId: 2,
    name: "",
    parentName: ""
  },
  {
    id: 4,
    parentId: 3,
    name: "",
    parentName: ""
  },
  {
    id: 5,
    parentId: 4,
    name: "",
    parentName: ""
  },
  {
    id: 6,
    parentId: 0,
    name: "",
    parentName: ""
  },
  {
    id: 7,
    parentId: 6,
    name: "",
    parentName: ""
  }
]

let res = handleTableData(tableData)

console.log(res)
Menu