在项目中经常遇到需要处理后台给的数据情况,有的数据需要处理成树形结构进行展示,有的数据需要一维数组进行过滤
应用场景:
数据demo:
// 层级数据:
tree = [
{
id:1, name: 'hahha', chilren:[
{id: 2, name: 'heiehi', chilren: []},
{id: 3, name: 'heiehi2', chilren: []},
]
},
{
id:4, name: 'hahha2', chilren:[
{id: 5, name: 'heiehi3', chilren: []},
{id: 6, name: 'heiehi4', chilren: []},
]
}
]
// 扁平数据:
list = [
{ id:1, name: 'hahha' },
{ id:2, name: 'heiehi' },
{ id:3, name: 'heiehi2' },
{ id:4, name: 'hahha2' },
{ id:5, name: 'heiehi3' },
{ id:6, name: 'heiehi4' },
]
1、数组扁平化
数组扁平化是指把一个有层级结构的数据,处理成无层级的数据,简单来说就是把数据的children放到一维数据当中
处理方法:循环堆置为一个一维数组
树形结构数据扁平化处理方法比较简单,就是循环数据就可以了
下面用一个新思路迭代解决,原先利用递归处理方法比较简单:
// 方法1:递归
function treeToList(tree) {
let arr = []
for(item of tree) {
if(item.children && item.children.length > 0){
let sitem = { ...item }
delete sitem.children
arr = arr.concat(sitem, treeToList(item.children))
} else {
delete item.children
arr.push(item)
}
}
return arr
}
// 方法2:迭代
export function treeToList(tree) {
var queen = []
var out = []
queen = queen.concat(tree)
while(queen.length) {
var first = queen.shift()
if (first.children) {
queen = queen.concat(first.children)
delete first.children
}
out.push(first)
}
return out
}
可以看到递归消耗的时间几乎是迭代的两倍
2、数组层级化
// 方法1:
export function translateDataToTree(arr) {
return arr.filter((father) => {
let branchArr = arr.filter((child) => father.id == child.parentId)
branchArr.length > 0 ? father.children = branchArr : ''
return father.parentId == ''
})
}
// 方法2:
export function translateDataToTree(arr) {
let temp = {}
let tree = {}
arr = deepClone(arr)
arr.forEach((item) => {
temp[item.id] = item
})
let tempKeys = Object.keys(temp)
tempKeys.forEach((key) => {
let item = temp[key]
let itemPId = item.parentId
let parentItemByPid = temp[itemPId]
if (parentItemByPid) {
if (!parentItemByPid.children) {
parentItemByPid.children = []
}
parentItemByPid.children.push(item)
} else {
tree[item.id] = item
}
})
return Object.keys(tree).map((key) => tree[key])
}
// 方法3:
export function translateDataToTree(data, parentId = '') {
let tree = []
let temp
data.forEach((item, index) => {
if (data[index].parentId === parentId) {
let obj = data[index]
temp = translateDataToTree(data, data[index].id)
if (temp.length > 0) {
obj.children = temp
}
tree.push(obj)
}
})
return tree
}
以下是时间对比,方法1和2差不多,方法3的时间明显较长,相比方法1慢了6.6倍多!!
方法1,2用于不同场景,可以看到方法1是按照接口给的顺序排序,而方法2则是根据id排序