JavaScript中基于元素值关联关系的数组分组实现问题
根据元素关联关系对二维数组分组的解决方案
需求说明
给定二维数组,其中每个子数组表示两个元素存在关联关系,需要将所有直接或间接关联的元素归为同一组,最终输出分组后的二维数组。
输入示例:
const arr = [ [123, 243], [123, 435], [736, 987], [987, 774], [123, 666], [774, 999], [98, 980], // 注:原输入中的098是无效八进制数,改为98;若需保留前导零请改为字符串'098' ];
期望输出:
[[123, 243, 435, 666],[736, 987, 774, 999],[98, 980]]
正确实现代码
这个问题本质是图的连通分量查找,可以通过邻接表+DFS(深度优先搜索)实现:
function groupConnectedElements(arr) { // 构建邻接表:记录每个节点的所有关联节点 const adjacency = new Map(); // 收集所有出现过的节点 const allNodes = new Set(); // 遍历输入数组,填充邻接表和节点集合 arr.forEach(([a, b]) => { allNodes.add(a); allNodes.add(b); // 双向添加关联关系 if (!adjacency.has(a)) adjacency.set(a, []); adjacency.get(a).push(b); if (!adjacency.has(b)) adjacency.set(b, []); adjacency.get(b).push(a); }); const visited = new Set(); const result = []; // 遍历所有节点,处理未访问的节点 allNodes.forEach(node => { if (!visited.has(node)) { const component = []; // 用DFS遍历整个连通分量 const stack = [node]; visited.add(node); while (stack.length > 0) { const current = stack.pop(); component.push(current); // 遍历当前节点的所有邻居 adjacency.get(current)?.forEach(neighbor => { if (!visited.has(neighbor)) { visited.add(neighbor); stack.push(neighbor); } }); } result.push(component); } }); return result; } // 测试代码 const arr = [ [123, 243], [123, 435], [736, 987], [987, 774], [123, 666], [774, 999], [98, 980], ]; console.log(groupConnectedElements(arr));
代码逻辑说明
- 邻接表构建:用
Map存储每个元素的所有关联元素,确保可以快速查找任意元素的关联对象 - 节点集合:收集所有出现过的元素,避免遗漏任何节点
- 访问标记:用
Set记录已处理的节点,防止重复加入不同分组 - DFS遍历:从一个未访问的节点出发,迭代遍历所有连通的节点,将它们归为同一组
原代码问题分析
你的代码未能实现需求的核心原因:
- 没有建立完整的关联关系链,仅查找包含单个值的子数组,无法处理
736→987→774→999这类间接关联的情况 checkVal函数的递归逻辑混乱,返回的是嵌套数组,无法将所有关联元素整合为一个完整分组- 去重逻辑仅针对重复的子数组,而非合并关联的子数组
内容的提问来源于stack exchange,提问作者Koperumsozhan VR
相关产品推荐
相关产品推荐

