findTreeNode.js

import { __values } from "tslib";
import { isArray, isObject } from 'ut2';
/**
 * 查找树结构数据节点
 *
 * @static
 * @alias module:Tree.findTreeNode
 * @since 4.14.0
 * @param {Object[]} tree 树结构数据
 * @param {function} predicate 遍历每一项执行的函数,参数是当前遍历到的节点数据,如果返回 `Truthy` ,将返回该节点
 * @param {string} [childrenField='children'] 子级字段名
 * @returns {Object|undefined}
 * @example
 * const menus = [{ id: '1', name: '首页', code: 'trade', pid: null }, { id: '2', name: '交易管理', code: 'trade', pid: null, children: [{ id: '3', name: '交易查询', code: 'trade-1', pid: '2', children: [{ id: '4', name: '交易查询-查询操作', code: 'trade-1-1', pid: '3' }]}]}, { id: '5', name: '权限管理', code: 'authorization', pid: null, children: [{ id: '6', name: '角色管理', code: 'authorization-1', pid: '5' }, { id: '7', name: '用户管理', code: 'authorization-2', pid: '5' }]}];
 *
 * findTreeNode(menus, item=>item.id === '2');
 * // {id: '2', name: '交易管理', code: 'trade', pid: null, children: [ { id: '3', name: '交易查询', code: 'trade-1', pid: '2', children: [{ id: '4', name: '交易查询-查询操作', code: 'trade-1-1', pid: '3' }]}]}
 *
 * findTreeNode(menus, item=>item.id === '7');
 * // { id: '7', name: '用户管理', code: 'authorization-2', pid: '5' }
 *
 * findTreeNode(menus, item=>item.id === 'not found');
 * // undefined
 */
function findTreeNode(tree, predicate, childrenField) {
    var e_1, _a;
    if (childrenField === void 0) { childrenField = 'children'; }
    var stack = [];
    var node;
    if (!isArray(tree)) {
        return node;
    }
    try {
        for (var tree_1 = __values(tree), tree_1_1 = tree_1.next(); !tree_1_1.done; tree_1_1 = tree_1.next()) {
            var item = tree_1_1.value;
            stack.push(item);
            while (stack.length) {
                var temp = stack.pop();
                if (predicate(temp)) {
                    node = temp;
                    break;
                }
                if (isObject(temp)) {
                    // @ts-ignore
                    var childs = temp[childrenField];
                    if (isArray(childs) && childs.length > 0) {
                        childs.forEach(function (c) {
                            stack.push(c);
                        });
                    }
                }
            }
            if (node) {
                break;
            }
        }
    }
    catch (e_1_1) { e_1 = { error: e_1_1 }; }
    finally {
        try {
            if (tree_1_1 && !tree_1_1.done && (_a = tree_1.return)) _a.call(tree_1);
        }
        finally { if (e_1) throw e_1.error; }
    }
    return node;
}
export default findTreeNode;