import _ from "lodash"; /** * @description 在树结构中查找路径 * @param {Object[]} tree - 树的根节点数组 * @param {Function} predicate - 要查找的目标条件 * @param {string} children - 属性名,默认`children` * @param {string[]} path - 当前路径(递归用) * @returns {Object[] | null} - 返回路径数组,如果没找到返回 null */ export function findTreePath(tree, predicate, children = 'children', path = []) { if (!Array.isArray(tree)) throw new TypeError('tree must be an array') if (typeof predicate !== 'function') throw new TypeError('predicate must be a function') for (const node of tree) { if (!node) continue // 添加当前节点到路径 const currentPath = [...path, node]; // 检查当前节点的值是否匹配 if (predicate(node)) return currentPath; // 如果有子节点,递归查找 if (node[children]?.length) { const result = findTreePath(node[children], predicate, children, currentPath); if (result) { return result; // 找到路径则返回 } } } // 如果未找到目标值,返回 null return null; } export function findTreeNode(tree, predicate, children = 'children') { const path = findTreePath(tree, predicate, children) return _.last(path) } export function convertStandardTree( root, labelKey = 'label', valueKey = 'value', childrenKey = 'children', toLabel = 'label', toValue = 'value', toChildren = 'children') { const convertor = (node) => ({ [toLabel]: node[labelKey], [toValue]: node[valueKey], [toChildren]: node[childrenKey]?.map(convertor) }) const arrRoot = Array.isArray(root) ? root : [root] return arrRoot.map(convertor) } export function fillTreeChildCount(tree) { const fillChildCount = (node) => { node.childCount = node.children?.length || 0 node.children?.forEach(child => fillChildCount(child)) } [].concat(tree).forEach(node => fillChildCount(node)) } export function fillTreeParentBridge(tree) { const fillParent = (node, parent = null, root = null) => { node.parent = parent node.root = root if (!node.children?.length) return node.children.forEach(child => fillParent(child, node, root || node)) } [].concat(tree).forEach(node => fillParent(node)) }