数组转 tree目前发现就三种方式,js版本实现了三种
初始化数据
let arr = [{name: "李四", id: 2, pid: 0},// []
{name: "王五", id: 3, pid: 0}, // []
{name: "赵六", id: 4, pid: 3}, // []
{name: "吗六", id: 9, pid: 3}, // []
{name: "张三", id: 7, pid: 9}, // []
{name: "张五", id: 10, pid: 4}, // []
]
1. 递归模式
/**
* 递归模式,数组转tree
* @param arr 目标数组
* @param pid 第一级 目标id
* @returns {*[]} tree
* [
* { name: '李四', id: 2, pid: 0, children: [] },
* { name: '王五', id: 3, pid: 0, children: [ [Object], [Object] ] }
* ]
* @constructor
*/
function ArrayToTree(arr, pid = 0) {
// 判断是否是数组 不是数组就返回 []
if (!Array.isArray(arr) || !arr.length) return [];
let newArr = []
arr.forEach(item => {
// 判断 当前item.pid 和 传入的pid 是否相等,相等就push 进去
if (item.pid == pid) {
newArr.push({
...item, children: ArrayToTree(arr, item.id)
})
}
})
return newArr
}
2. 双重循环
/**
* 双重for循环模式,数组转tree
* @param arr
* @returns {any}
* [
* { name: '李四', id: 2, pid: 0 },
* { name: '王五', id: 3, pid: 0, children: [ [Object], [Object] ] }
* ]
*/
function arrToTreeOne(arr,pid=0){
if (!Array.isArray(arr) || !arr.length) return [];
// 克隆一个新数组
let copyArr = Object.assign([],arr)
// 双重循环
let newArr = copyArr.filter(item =>{
arr.forEach(v =>{
// 判断 id 和 pid 是否相同
if(item.id === v.pid){
// 相同就判断有没有 children , 有就push进去v 没有就 [v]
if(item.children){
item.children.push(v)
}else{
item.children = [v]
}
}
})
if (item.pid == pid) return item
})
return newArr
}
3. map特性模式
/**
* map模式 ,数组转tree
* @param arr 目标数组
* @param pid 第一级 目标id
* @returns {*[]}
* [
* { name: '李四', id: 2, pid: 0 },
* { name: '王五', id: 3, pid: 0, child: [ [Object], [Object] ] }
* ]
* @constructor
*/
function ArrAyToTreeMap(arr,pid=0) {
if (!Array.isArray(arr) || !arr.length) return [];
let map = {}
// 把map的key 是item.id value是item
arr.forEach(item => map[item.id] = item)
let res = []
arr.forEach(item => {
// item.pid 和 map的key 是否存在, 存在就 true 不存在就false
let mapPid = map[item.pid]
// 把pid顶级相等的插入进去
if (item.pid == pid){
res.push(item)
}else {
if (mapPid) {
// 存在就 判断 map的child 是否存在 ,不存在就赋值一个数组,在添加 item
((mapPid.child || (mapPid.child = [])).push(item))
}
}
})
return res;
}
4. 过滤器的模式
/**
* 过滤器的模式,数组转tree
* @param arr
* @returns [] 数组对象的 tree , 有需要自己在 过滤一下指定的 pid
* [
* { name: '李四', id: 2, pid: 0, children: [] },
* { name: '王五', id: 3, pid: 0, children: [ [Object], [Object] ] }
* ]
*/
function arrToTreeArray(arr,pid=0){
if (!Array.isArray(arr) || !arr.length) return [];
// 克隆一个新数组
let copyArr = arr.filter(item =>{
let children = arr.filter(v => item.id === v.pid)
item.children = children.length > 0 ? item.children = children : []
if (item.pid == pid){
return item
}
})
return copyArr
}