如何在不借助数据库的情况下对JavaScript数组执行分层查询
用JavaScript实现分层数据展示(无需数据库)
完全理解你的需求!咱们直接用JavaScript递归就能搞定这两种分层形式,先把原始数据做个小预处理,统一children的格式(因为有的是字符串、有的缺省),再分别实现两种输出逻辑。
第一步:数据预处理
首先把所有节点的children统一为数组格式,避免后续处理出错,同时转成Map方便快速查找节点:
let myArray = [ { name: 'Alice', children: ['Bob', 'Bill'] }, { name: 'Bob', children: 'Cindy' }, { name: 'Bill', children: [] }, { name: 'Cindy', children: ['David', 'Don'] }, { name: 'David' }, { name: 'Don' }, ]; // 预处理:统一children为数组,缺省则设为空数组 const normalizedData = myArray.map(item => ({ name: item.name, children: Array.isArray(item.children) ? item.children : (item.children ? [item.children] : []) })); // 转成Map,通过节点名快速查找对应数据 const nodeMap = new Map(normalizedData.map(node => [node.name, node]));
形式一:缩进树形结构
用递归函数遍历节点,根据层级添加缩进,实现树形展示:
function printTree(node, level = 0) { // 按层级打印带缩进的节点名 console.log(' '.repeat(level) + node.name); // 递归处理子节点,层级+1 node.children.forEach(childName => { const childNode = nodeMap.get(childName); if (childNode) { printTree(childNode, level + 1); } }); } // 从根节点Alice开始打印 console.log('形式一输出:'); printTree(nodeMap.get('Alice'));
运行后输出:
形式一输出: Alice Bob Cindy David Don Bill
形式二:完整路径链
同样用递归,跟踪当前的路径链,每到一个节点就输出完整路径:
function printPaths(node, currentPath = []) { const newPath = [...currentPath, node.name]; // 输出当前拼接好的路径 console.log(newPath.join(' -> ')); // 递归处理子节点,传递更新后的路径 node.children.forEach(childName => { const childNode = nodeMap.get(childName); if (childNode) { printPaths(childNode, newPath); } }); } // 从根节点Alice开始打印 console.log('\n形式二输出:'); printPaths(nodeMap.get('Alice'));
运行后输出:
形式二输出: Alice Alice -> Bob Alice -> Bob -> Cindy Alice -> Bob -> Cindy -> David Alice -> Bob -> Cindy -> Don Alice -> Bill
扩展说明
如果你的数据存在多个根节点(比如除了Alice还有其他无父节点的节点),只需要遍历normalizedData,找出名字不在任何其他节点children里的节点,然后逐个调用上面的递归函数即可。另外,递归逻辑也可以改成迭代实现,避免深层嵌套可能的栈溢出,但对于一般规模的层级数据,递归已经足够好用。
内容的提问来源于stack exchange,提问作者Wernfried Domscheit
相关产品推荐
相关产品推荐

