【JS】前端js实现树形结构:递归拼接树形结构与使用filter函数,不使用递归实现树形结构, O(n)解法

本文介绍了前端开发中树形结构的几种实现方式,包括使用递归实现树形菜单列表及利用filter函数构建地理位置级联选择。同时提供了一种优化后的O(n)解法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

前端树形结构一般用于网页的地理位置输入框,地理位置级联选择,人员的部门选择等。
树形选择
常见的做法是使用递归实现树形结构,还有的使用filter函数可直接实现树形结构。

一、递归实现树形结构

递归:递归函数就是函数对自身的调用,是循环运算的一种算法模式。

经典例子之递归求和:

function sum(n) {
  if (n == 1) return 1
  return sum(n - 1) + n
}

递归必须由以下两部分组成:

  • 递归调用的过程
  • 递归终止的条件:在没有限制的情况下,递归运算会无终止地自身调用。因此,在递归运算中要结合 if 语句进行控制,只有在某个条件成立时才允许执行递归,否则不允许调用自身。

如下实现一个菜单列表的树结构拼接:

let arr = [
	{ id: 1, parent: null, text: '菜单1' },
	{ id: 11, parent: 1, text: '菜单1-1' },
	{ id: 111, parent: 11, text: '菜单1-1-1' },
	{ id: 112, parent: 11, text: '菜单1-1-2' },
	{ id: 12, parent: 1, text: '菜单1-2' },
	{ id: 2, parent: null, text: '菜单2' },
	{ id: 21, parent: 2, text: '菜单2-1' },
	{ id: 22, parent: 2, text: '菜单2-2' },
];
function getTreeList(rootList, id, list) {
	for (item of rootList) {
		if (item.parent == id) {
			list.push(item);
		}
	}
	for (i of list) {
		i.children = [];
		getTreeList(rootList, i.id, i.children);
	}
	return list;
}
let res = getTreeList(arr, null, []);
console.log(res);

打印:
在这里插入图片描述

二、使用filter函数实现树形结构

数据复杂度O(n^2)。数据多了时间复杂度爆表。

let cityList = [
	{id: 1, parentId: 0, name:'江苏省'},
	{id: 2, parentId: 0, name:'广东省'},
	{id: 3, parentId: 0, name:'安徽省'},
	{id: 4, parentId: 1, name:'苏州市'},
	{id: 5, parentId: 1, name:'无锡市'},
	{id: 6, parentId: 1, name:'南京市'},
	{id: 7, parentId: 2, name:'广州市'},
	{id: 8, parentId: 2, name:'深圳市'},
	{id: 9, parentId: 3, name:'合肥市'},
	{id: 10, parentId: 4, name:'工业园区'},
	{id: 11, parentId: 4, name:'吴中区'},
	{id: 12, parentId: 4, name:'姑苏区'},
	{id: 13, parentId: 9, name:'肥东区'},
	{id: 14, parentId: 9, name:'肥西区'},
	{id: 15, parentId: 6, name:'江宁区'},
	{id: 16, parentId: 6, name:'玄武区'}
];
let treeArr = [];
cityList.forEach(item => {
	if(item.parentId === 0){
		treeArr.push(item);
	}
	// 每一项都添加一个children
	item.children = cityList.filter(child => child.parentId === item.id);
});
console.log(treeArr);

打印:
在这里插入图片描述

三、终极优化方案

上面的方案时间复杂度可能有点高,下面是借鉴来的O(n)解法,可供大家学习参考:

function jsonToTree(arr) {
	// 使用map转存,增加查找效率
	const map = new Map();
	arr.forEach((item) => {
    map.set(item.id, item);
	});

	// 将子元素依次放入父元素中
	const res = [];
	arr.forEach((item) => {
		const parent = map.get(item.parentId);
		if (parent) {
			(parent.children || (parent.children = [])).push(item);
		} else {
			res.push(item);
		}
	});
	console.log(res);
}

四、总结

暂时写这么多,下次优化,如果有大佬优化一下就在评论区指导一下下,谢谢.

三连一下

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

卸载引擎

如果对您有帮助,请赏个饭吃

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值