点击查看代码
/**
* @description 查找包含自身节点的父代节点
* @param list 列表数据
* @param id 节点 id
* @param pid 节点的父id
*/
export function listToTree(list, id, pid) {
list.forEach((node) => {
const pNdoe = list.find((row) => row[id] === node[pid])
if (pNdoe) {
pNdoe.children = pNdoe.children || []
pNdoe.children.push(node)
}
})
return list.filter((node) => !node[pid])
}
// data 是树型数组
// key 是String 对象中的key值
// value 是key值符合的条件
export function getAllChidlren(data, key, value) {
var result = [];
var fn = function(data) {
if (Array.isArray(data)) { // 判断是否是数组并且没有的情况下,
data.forEach(item => {
if (item[key] === value) { // 数据循环每个子项
result.push(item); // 返回的结果等于每一项
} else if (item.children) {
fn(item.children); // 递归调用下边的子项
}
})
}
}
fn(data); // 调用一下
return result;
}
// 树结构过滤即保留某些符合条件的节点,剪裁掉其它节点。一个节点是否保留在过滤后的树结构中,取决于它以及后代节点中是否有符合条件的节点。可以传入一个函数描述符合条件的节点:
export function treeFilter(tree, func) {
// 使用map复制一下节点,避免修改到原树
return tree.map(node => ({ ...node })).filter(node => {
node.children = node.children && treeFilter(node.children, func)
return func(node) || (node.children && node.children.length)
})
}
// 查找节点其实就是一个遍历的过程,遍历到满足条件的节点则返回,遍历完成未找到则返回null。类似数组的find方法,传入一个函数用于判断节点是否符合条件
export function treeFind(tree, func) {
for (const data of tree) {
if (func(data)) return data
if (data.children) {
const res = treeFind(data.children, func)
if (res) return res
}
}
return null
}
// 因为不知道符合条件的节点在哪个子树,要用到回溯法的思想。查找路径要使用先序遍历,维护一个队列存储路径上每个节点的id,假设节点就在当前分支,如果当前分支查不到,则回溯
export function treeFindPath(tree, func, path = []) {
if (!tree) return []
for (const data of tree) {
path.push(data.id)
if (func(data)) return path
if (data.children) {
const findChildren = treeFindPath(data.children, func, path)
if (findChildren.length) return findChildren
}
path.pop()
}
return []
}
/**
* @description 遍历 tree 给 tree 添加数据
* @param tree tree 数据
* @param func 返回追加的属性{key1:value1,key2:value2}
*/
export function formatTree(treeData, func) {
const dfs = (treeData) => {
for (const node of treeData) {
if (func(node)) {
Object.assign(node, func(node))
}
if (node.children && node.children.length) {
dfs(node.children)
}
}
return treeData
}
return dfs(treeData)
}
//js树结构根据条件查找节点返回节点路径
export function findPathbyName(tree, name, path = []) {
if (typeof path === 'undefined') {
path = []
}
for (let i = 0; i < tree.length; i++) {
let tempPath = [...path]
tempPath.push(tree[i].meta.title)
if (tree[i].name === name) {
return tempPath
}
if (tree[i].children) {
const reuslt = findPathbyName(tree[i].children, name, tempPath)
if (reuslt) {
return reuslt
}
}
}
}