Array 转 树状结构
实现思路
- 按照pid分组,分组可以大大减少递归次数。。(Array分组的最好方式是用对象接收Array的项,该对象的key值就是分组凭证)
- 按照pid和id的匹配 递归 已分组的数据。
代码
export function getTrees(list, parentId = '0', pKey = 'pid', cKey = 'id') {
let items = {}
for (let i = 0; i < list.length; i++) {
let key = list[i][pKey]
if (items[key]) {
items[key].push(list[i])
} else {
items[key] = []
items[key].push(list[i])
}
}
return formatTree(items, parentId, cKey)
}
function formatTree(items, parentId, cKey) {
let result = []
if (!items[parentId]) {
return result
}
for (let t of items[parentId]) {
const temp = formatTree(items, t[cKey], cKey)
if (temp.length > 0) {
t.children = temp
}
result.push(t)
}
return result
}
根据节点值查找树形结构中的路径、子树
实现思路
- 使用深度优先算法,递归按照层级查找
- 找到指定节点,返回路径
代码
export function findTreePath(value, tree, attr = 'id', childAttr = 'children') {
if (!(tree instanceof Array)) {
console.error('tree: 请传入树形数组进行过滤!')
return []
}
if (tree.length === 0) return []
for (let i = 0; i < tree.length; i++) {
const item = tree[i]
if (item[attr] === value) {
return [item[attr]]
}
if (item[childAttr]) {
const path = findTreePath(value, item[childAttr], attr, childAttr)
if (path.length > 0) {
path.splice(0, 0, item[attr])
return path
}
}
}
return []
}
export function findTreeNode(value, tree, attr = 'id', childAttr = 'children') {
if (!(tree instanceof Array)) {
console.error('tree: 请传入树形数组进行过滤!')
return null
}
if (tree.length === 0) return
for (let i = 0; i < tree.length; i++) {
const item = tree[i]
if (item[attr] === value) {
return item
}
if (item[childAttr]) {
const node = findTreeNode(value, item[childAttr], attr, childAttr)
if (node) {
return node
}
}
}
return null
}