在数组的映射中不使用图形查找循环依赖

Posted

技术标签:

【中文标题】在数组的映射中不使用图形查找循环依赖【英文标题】:Find cyclic dependency without using graph in Map of array 【发布时间】:2019-10-04 02:50:38 【问题描述】:

我有一个像下面这样的对象:

var myMap = 
    v1: ['v2', 'v4', 'v5'],
    v2: ['x', 'v4', 'y'],
    v3: ['v2', 'v4', 'v5'],
    v4: ['e', 'v1', 'v5'],
    v5: ['v2', 'v4', 'v3'],
;

我必须找到循环实体图而不将其转换为图形。

输出如下:

var myDep = 
    v1: isCyclic: true, cyclicDependents: ['v4'],
    v2: isCyclic: false, cyclicDependents: [],
    v3: isCyclic: true, cyclicDependents: ['v5'],
    v4: isCyclic: true, cyclicDependents: ['v1', 'v5'],
    v5: isCyclic: true, cyclicDependents: ['v4', 'v3'],
;

我尝试了以下方法:

var graph = 
  v1: ["v2", "v4", "v5"],
  v2: ["x", "v4", "y"],
  v3: ["v2", "v4", "v5"],
  v4: ["e", "v1", "v5"],
  v5: ["v2", "v4", "v3"]
;

var myDep = 
  v1:  isCyclic: false, cyclicDependents: [] ,
  v2:  isCyclic: false, cyclicDependents: [] ,
  v3:  isCyclic: false, cyclicDependents: [] ,
  v4:  isCyclic: false, cyclicDependents: [] ,
  v5:  isCyclic: false, cyclicDependents: [] 
;

myDep = Object.keys(graph).reduce((a, b) => 
  graph[b] &&
graph[b].forEach(d => 
  if (graph[d] && ~graph[d].indexOf(b)) 
    a[b].isCyclic = true;
    a[b].cyclicDependents.push(d);
  
);
  return a;
, myDep);

console.log(myDep);

有没有其他方法可以提高性能。我认为以迭代方式使用 JSON.stringify 和 try catch 块可能也是一种方法。但我不确定它的性能会更高/更低。

【问题讨论】:

您好,为什么要限制您的问题?为什么说“不将其转换为图形”?您是否有不想先转换为图表的原因?您是否已经知道如何从图表中做到这一点并正在寻找不同的方法? @Ray Toal,感谢您的提问。是的,我对 Graph 有一点想法。我不想使用 Graph,因为它会引入额外的 LOC(图形、节点等的定义),并且在我的代码中它只需要一次,因此希望在低 LOC 中完成它以提高代码的可读性。 【参考方案1】:

您可以使用一个函数来检查循环性质并存储访问过的节点以防止永远循环。

结果是一个具有循环起始键及其节点的对象。想要的格式留给读者作为练习。

function isCyclic(node, target, [...visited] = []) 
    if (node === target) return true;
    if (visited.includes(node) || !myMap[node]) return false;
    visited.push(node);
    return myMap[node].some(n => isCyclic(n, target, visited));


var myMap =  v1: ['v2', 'v4', 'v5'], v2: ['x', 'v4', 'y'], v3: ['v2', 'v4', 'v5'], v4: ['e', 'v1', 'v5'], v5: ['v2', 'v4', 'v3'] ,
    result = ;
   
Object.entries(myMap).forEach(([k, v]) => result[k] = v.filter(n => isCyclic(n, k)));

console.log(result);
.as-console-wrapper  max-height: 100% !important; top: 0; 

【讨论】:

以上是关于在数组的映射中不使用图形查找循环依赖的主要内容,如果未能解决你的问题,请参考以下文章

Spring是如何解决循环依赖的?

Oracle:如何循环并查找表之间的依赖/依赖关系,以便为每个表执行插入/更新操作?

精通Mybatis之结果集处理流程与映射体系(重点mybatis嵌套子查询,循环依赖解决方案)

尽管依赖项没有变化,useEffect 运行无限循环

MFC 在 for 循环中绘图

从 api 获取时反应 useEffect 无限循环