树结构,转换
type TreeNode = {
children?: TreeNode[]
[key: string]: any
}
/**
* 给树结构补充 canSelect 字段
* 规则:
* 1. 当前级别 >= 3,可选
* 2. 当前级别 < 3,但没有子节点,也可选
* 3. 其他不可选
*
* @param tree 树数据
* @param level 起始层级,默认从 1 开始
* @returns 新树
*/
export function setTreeCanSelect<T extends TreeNode>(
tree: T[],
level = 1
): Array<T & { canSelect: boolean }> {
if (!Array.isArray(tree)) return []
return tree.map((node) => {
const children = Array.isArray(node.children) ? node.children : []
const hasChildren = children.length > 0
const canSelect = level >= 3 || !hasChildren
return {
...node,
canSelect,
children: hasChildren
? setTreeCanSelect(children, level + 1)
: []
}
})
}
取值
type TreeNode = {
label: string
value: string | number
children?: TreeNode[]
[key: string]: any
}
/**
* 树拍平
*/
function flattenTree(tree: TreeNode[]): TreeNode[] {
const result: TreeNode[] = []
const dfs = (nodes: TreeNode[]) => {
nodes.forEach((node) => {
result.push(node)
if (node.children && node.children.length) {
dfs(node.children)
}
})
}
dfs(tree)
return result
}
/**
* 根据 valueList 获取节点对象列表
*/
export function getNodesByValues(
tree: TreeNode[],
valueList: Array<string | number>
): TreeNode[] {
if (!Array.isArray(tree) || !Array.isArray(valueList)) return []
const flatList = flattenTree(tree)
const valueSet = new Set(valueList)
return flatList.filter((node) => valueSet.has(node.value))
}
