filter__forEach_0">写一个JavaScript树形结构操作函数:filter
与 forEach
在JavaScript开发中,处理树形结构数据是一项常见的任务。本文将详细介绍两个用于操作树形结构数据的函数:filter
和 forEach
,包括它们的功能、使用方法以及具体示例。
filter__4">1. filter
函数
1.1 功能概述
filter
函数用于过滤树形结构数据。它会遍历树形结构中的每个节点,根据传入的过滤函数 func
来决定是否保留该节点。如果节点通过过滤函数的检查,或者该节点有子节点且子节点通过过滤,那么该节点将被保留在最终结果中。
1.2 函数定义
export const filter = <T = any>(
tree: T[],
func: (n: T) => boolean,
config: Partial<TreeHelperConfig> = {}
): T[] => {
config = getConfig(config)
const children = config.children as string
function listFilter(list: T[]) {
return list
.map((node: any) => ({...node }))
.filter((node) => {
node[children] = node[children] && listFilter(node[children])
return func(node) || (node[children] && node[children].length)
})
}
return listFilter(tree)
}
这里,T
是树形结构节点的数据类型,默认为 any
。tree
是包含树形结构节点的数组,func
是用于过滤节点的函数,config
是一个可选配置对象,用于指定树形结构中表示子节点的属性名。
1.3 使用方法
- 参数说明:
tree
: 必需,树形结构数据的根节点数组。func
: 必需,一个回调函数,接收一个节点作为参数,返回true
或false
,用于判断该节点是否应被保留。config
: 可选,配置对象,可用于指定树形结构中表示子节点的属性名,默认为{}
。
1.4 示例
假设我们有如下树形结构数据,表示一个公司的部门和员工:
javascript">const companyTree = [
{ id: 1, name: '总公司', type: 'department', children: [
{ id: 2, name: '研发部', type: 'department', children: [
{ id: 3, name: '前端组', type: 'team', children: [
{ id: 4, name: '张三', type: 'employee' },
{ id: 5, name: '李四', type: 'employee' }
]},
{ id: 6, name: '后端组', type: 'team', children: [
{ id: 7, name: '王五', type: 'employee' }
]}
]},
{ id: 8, name: '市场部', type: 'department', children: [
{ id: 9, name: '推广组', type: 'team', children: [
{ id: 10, name: '赵六', type: 'employee' }
]}
]}
]
];
现在我们要过滤出所有类型为 employee
的节点:
javascript">const filteredTree = filter(companyTree, (node) => node.type === 'employee');
console.log(filteredTree);
上述代码会输出所有员工节点组成的树形结构。
forEach__66">2. forEach
函数
2.1 功能概述
forEach
函数用于遍历树形结构数据。它会对树形结构中的每个节点执行传入的回调函数 func
,如果回调函数返回 true
,则终止遍历,以避免在大量节点场景下的无意义循环,防止浏览器卡顿。
2.2 函数定义
export const forEach = <T = any>(
tree: T[],
func: (n: T) => any,
config: Partial<TreeHelperConfig> = {}
): void => {
config = getConfig(config)
const list: any[] = [...tree]
const { children } = config
for (let i = 0; i < list.length; i++) {
if (func(list[i])) {
return
}
children && list[i][children] && list.splice(i + 1, 0,...list[i][children])
}
}
这里,T
同样是树形结构节点的数据类型,tree
是树形结构数据的根节点数组,func
是遍历节点时执行的回调函数,config
用于指定树形结构中表示子节点的属性名。
2.3 使用方法
- 参数说明:
tree
: 必需,树形结构数据的根节点数组。func
: 必需,一个回调函数,接收一个节点作为参数,返回一个值。如果返回true
,则终止遍历。config
: 可选,配置对象,可用于指定树形结构中表示子节点的属性名,默认为{}
。
2.4 示例
还是以上述公司树形结构数据为例,我们要找到名字为 李四
的员工节点,并输出其信息:
javascript">forEach(companyTree, (node) => {
if (node.name === '李四') {
console.log('找到李四:', node);
return true;
}
});
上述代码会在遍历到名字为 李四
的节点时输出其信息,并终止遍历。
通过这两个函数,我们可以方便地对树形结构数据进行过滤和遍历操作,提高开发效率。在实际应用中,可根据具体需求灵活调整和使用。