如何从二维数组映射构建有向加权图邻接表(Google Apps Script)
如何基于二维数组映射构建有向加权图的邻接表
问题描述
在Google Apps Script环境下开发,从Google Sheet读取数据得到的二维数组格式如下:
[['a', 'b', 2], ['b', 'a', 1, 'g', 7], ['c', 'd', 4], ['d', 'c', 3, 'g', 7], ['e', 'a', 1, 'c', 3], ['f', 'a', 1, 'c', 3], ['g', 'h', 8]]
需要将其转换为如下结构的有向加权图邻接表:
graph = { a: { b: 2 }, b: { a: 1, g: 7 }, c: { d: 4 }, d: { c: 3, g: 7 }, e: { a: 1, c: 3 }, f: { a: 1, c: 3 }, g: { h: 8 }, };
转换规则:
- 每个子数组第一个元素为源节点
- 子数组剩余元素按「邻接节点、边权重」两两成对,对应源节点的所有出边关系
- 子数组长度不固定,子数组总数量随数据源动态变化
此前尝试使用map、slice、splice、flat、展开运算符等方法均未得到符合预期的结果。
实现代码
直接用两层循环实现即可,逻辑清晰且兼容GAS运行环境,不会修改原始数组:
function buildWeightedGraph(rawData) { const graph = {}; for (const row of rawData) { // 取当前行第一个元素作为源节点 const sourceNode = row[0]; graph[sourceNode] = {}; // 步长设为2,两两配对读取邻接节点和对应权重 for (let i = 1; i < row.length; i += 2) { const neighbor = row[i]; const weight = row[i + 1]; graph[sourceNode][neighbor] = weight; } } return graph; } // 调用示例 const rawData = [['a', 'b', 2], ['b', 'a', 1, 'g', 7], ['c', 'd', 4], ['d', 'c', 3, 'g', 7], ['e', 'a', 1, 'c', 3], ['f', 'a', 1, 'c', 3], ['g', 'h', 8]]; const graph = buildWeightedGraph(rawData);
可选函数式写法
如果偏好reduce风格的写法,也可以用如下实现,效果完全一致:
const buildWeightedGraph = rawData => rawData.reduce((graph, row) => { const [source, ...edgePairs] = row; graph[source] = {}; for (let i = 0; i < edgePairs.length; i += 2) { graph[source][edgePairs[i]] = edgePairs[i + 1]; } return graph; }, {});
注意:不要用
splice处理原始数据,该方法会直接修改原数组,可能导致后续读取Sheet数据时出现异常。
内容的提问来源于stack exchange,提问作者malfeasanttaco
相关产品推荐
相关产品推荐

