如何基于JavaScript对象绘制邻接矩阵并统计值出现次数?
解决JavaScript邻接矩阵的节点出现次数统计问题
我来帮你搞定这个邻接矩阵的统计需求!你的核心问题是要统计每个节点(对象的键)对应的邻接数组里,各个节点的出现次数,最终生成指定格式的矩阵输出。下面一步步拆解实现思路和代码:
第一步:明确目标与准备工作
首先我们有给定的节点邻接关系对象:
var result = { "D5": ["D#5", "A#4", "D#5", "A#4"], "D#5": ["D5", "D5"], "A#4": ["G4", "D5", "F5"], "G4": ["A#4"], "F5": ["A#4"] };
我们需要生成的矩阵,行列都是所有唯一节点(D#5, A#4, D5, G4, F5),每个单元格是行节点指向列节点的次数。
第二步:收集并整理节点顺序
首先我们需要确定矩阵的行列顺序,这里直接匹配你想要的输出顺序:
// 手动指定行列顺序,和目标输出一致 const allNodes = ["D#5", "A#4", "D5", "G4", "F5"];
如果需要动态收集所有节点(比如后续对象可能变化),可以用这段代码自动收集去重:
// 动态收集所有节点(键 + 所有值元素) let allNodes = [...Object.keys(result)]; Object.values(result).forEach(arr => allNodes.push(...arr)); // 去重 allNodes = [...new Set(allNodes)]; // (可选)如果需要自定义排序,再调整顺序即可
第三步:统计节点出现次数
我们可以用两种方式实现统计:
方式一:基础遍历统计(适合小数据量)
先写一个工具函数,统计数组中某个元素的出现次数:
function countOccurrences(arr, target) { // 过滤出等于目标的元素,返回长度就是次数 return arr.filter(item => item === target).length; }
然后遍历每个节点,生成对应的行数据:
// 先输出矩阵的列标题 console.log(allNodes.join(' ')); // 遍历每个行节点,生成该行的统计数据 allNodes.forEach(node => { // 获取当前节点的邻接数组,不存在则用空数组 const adjacencyList = result[node] || []; // 对每个列节点统计出现次数 const counts = allNodes.map(colNode => countOccurrences(adjacencyList, colNode)); // 拼接并打印行内容 console.log(`${node} ${counts.join(' ')}`); });
方式二:预先生成频率映射(适合大数据量)
如果你的邻接数据量很大,预先生成每个节点的频率映射会更高效,避免重复遍历数组:
// 预先生成每个节点的邻接频率映射 const frequencyMap = {}; Object.keys(result).forEach(node => { frequencyMap[node] = result[node].reduce((acc, item) => { acc[item] = (acc[item] || 0) + 1; return acc; }, {}); }); // 生成矩阵输出 console.log(allNodes.join(' ')); allNodes.forEach(node => { const nodeFreq = frequencyMap[node] || {}; const counts = allNodes.map(colNode => nodeFreq[colNode] || 0); console.log(`${node} ${counts.join(' ')}`); });
运行结果
两种方式最终都会输出你想要的内容:
D#5 A#4 D5 G4 F5 D5 2 2 0 0 0 D#5 0 0 2 0 0 A#4 0 0 1 1 1 G4 0 1 0 0 0 F5 0 1 0 0 0
内容的提问来源于stack exchange,提问作者lukassz
相关产品推荐
相关产品推荐

