findTreeNodes.js

  1. import { forEach, isArray, isObject } from 'ut2';
  2. /**
  3. * 查找树结构数据多个节点
  4. *
  5. * @alias module:Tree.findTreeNodes
  6. * @since 4.15.0
  7. * @param {Object[]} tree 树结构数据
  8. * @param {function} predicate 遍历每一项执行的函数,参数是当前遍历到的节点数据,如果返回 Truthy ,返回结果将包含该节点
  9. * @param {string} [childrenField='children'] 子级字段名,默认`children`
  10. * @returns {Object[]}
  11. * @example
  12. * 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' }]}];
  13. *
  14. * findTreeNodes(menus, item=>item.id === '2');
  15. * // [{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'}]}]}]
  16. *
  17. * findTreeNodes(menus, item=>item.name.indexOf('管理') > -1);
  18. * // [{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'}]},{id:'7',name:'用户管理',code:'authorization-2',pid:'5'},{id:'6',name:'角色管理',code:'authorization-1',pid:'5'}]
  19. *
  20. * findTreeNodes(menus, item=>item.id === '1' || item.id === '7');
  21. * // [{id:'1',name:'首页',code:'trade',pid:null},{id:'7',name:'用户管理',code:'authorization-2',pid:'5'}]
  22. *
  23. * findTreeNodes(menus, item=>item.id === 'not found');
  24. * // []
  25. */
  26. function findTreeNodes(tree, predicate, childrenField = 'children') {
  27. const stack = [];
  28. const nodes = [];
  29. if (isArray(tree)) {
  30. forEach(tree, (item) => {
  31. stack.push(item);
  32. while (stack.length) {
  33. const temp = stack.pop();
  34. if (predicate(temp)) {
  35. nodes.push(temp);
  36. }
  37. if (isObject(temp)) {
  38. // @ts-ignore
  39. const childs = temp[childrenField];
  40. if (isArray(childs) && childs.length > 0) {
  41. childs.forEach((c) => {
  42. stack.push(c);
  43. });
  44. }
  45. }
  46. }
  47. });
  48. }
  49. return nodes;
  50. }
  51. export default findTreeNodes;