有时候,讲的文字太多反而不太理解,对于我们天天和代码打交道,多说无益,我们直接上代码。本文汇整了几个简单的前端常用的树的遍历与数据获取,可根据注释和标题进行阅读,运行结果可复制到浏览器直接运行。
如何使用递归遍历一个树,并自下向上,优先输出叶子节点后再输出根节点
const tree = {
id: 1001,
name: '1001',
children: [
{
id: 100101,
name: '100101',
children: [
{id: 10010101, name: '10010101', children: []},
{id: 10010102, name: '10010102', children: []},
]
},
{
id: 100102,
name: '100102',
children: [
{id: 10010201, name: '10010201', children: []},
{id: 10010202, name: '10010202', children: []},
{id: 10010203, name: '10010203', children: []}
]
},
]
};
function getLeaf(node) {
if(!node.children || !node.children.length) {
console.log('叶子节点', node)
return
}
for(const child of node.children){
getLeaf(child)
}
console.log('父节点', node)
}
getLeaf(tree)
js中树结构根据条件查找节点返回节点路径
const tree = {
id: 1001,
name: '1001',
children: [
{
id: 100101,
name: '100101',
children: [
{id: 10010101, name: '10010101', children: []},
{id: 10010102, name: '10010102', children: []},
]
},
{
id: 100102,
name: '100102',
children: [
{id: 10010201, name: '10010201', children: []},
{id: 10010202, name: '10010202', children: []},
{id: 10010203, name: '10010203', children: []}
]
},
]
};
// tree 树
// key 查找的叶子节点key名称
// name 叶子页面的名称
// value 查找的叶子节点的值
function getPathById(tree, key, name, value){
//定义变量保存当前结果路径
let temppath = [];
let tempname = [];
try {
function getNodePath(node) {
temppath.push(node[key]);
tempname.push(node[name])
//找到符合条件的节点,通过throw终止掉递归
if (node[key] === value) throw ('找到了');
if (node.children && node.children.length) {
for (let i = 0; i < node.children.length; i++) {
getNodePath(node.children[i]);
}
//当前节点的子节点遍历完依旧没找到,则删除路径中的该节点
temppath.pop();
tempname.pop();
} else {
//找到叶子节点时,删除路径当中的该叶子节点
temppath.pop();
tempname.pop();
}
}
getNodePath(tree);
} catch (e) {
let result = {
path: temppath.filter(o => !!o),
name: tempname.filter(o => !!o),
}
return result
}
}
getPathById(tree, 'id', 'name', 10010202);
树的指定字段合并到一个数组,然后去重
const tree = {
id: 1001,
name: '1001',
names: ['1001'],
children: [
{
id: 100101,
name: '100101',
names: ['100101'],
children: [
{id: 10010101, name: '10010101', names: ['10010101'], children: []},
{id: 10010102, name: '10010102', names: ['10010102'], children: []},
]
},
{
id: 100102,
name: '100102',
names: ['100102'],
children: [
{id: 10010201, name: '10010201', names: ['10010201'], children: []},
{id: 10010202, name: '10010202', names: ['10010202'], children: []},
{id: 10010203, name: '10010203', names: ['10010203'], children: []}
]
},
]
};
const getAllList = (tree) => {
let list = []
function circulTree(node) {
list = [...list, ...(node.names || [])] // names合并到一个数组
if(!node.children || !node.children.length) return
for(const child of node.children) {
circulTree(child)
}
}
circulTree(tree)
// 这里返回过滤是因为多场景兼容,因为getAllList接受的是一个对象
// 如果names里面的是对象,根据id去重
// return list.filter((x,i) => list.findIndex(o => o.id === x.id) === i)
// 如果是字符串,根据每一项进行去重
return Array.from(new Set(list))
}
getAllList(tree)